[英]python video streaming using opencv and web socket
i'm trying to write a python script that streams video to browser using web socket.我正在尝试编写一个 python 脚本,该脚本使用网络套接字将视频流式传输到浏览器。 I'm using opencv as client to send frames via socket and browser script receive and display it on a browser.
我使用 opencv 作为客户端通过套接字发送帧,浏览器脚本接收并在浏览器上显示它。 single image are displayed in browser but issue occurs while streaming video not able to display it on browser.
单个图像显示在浏览器中,但流视频无法在浏览器上显示时出现问题。 python flask works fine but there are few issues so i have planned use web socket for browser display
python Flask 工作正常,但问题很少,所以我计划使用 web socket 进行浏览器显示
client code sends frame to server using opencv and socket客户端代码使用 opencv 和套接字将帧发送到服务器
import cv2
import numpy as np
import socket
import sys
import pickle
import struct ### new code
cap=cv2.VideoCapture("test.avi")
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('0.0.0.0',8082))
while True:
ret,frame=cap.read()
data = pickle.dumps(frame) ### new code
clientsocket.sendall(struct.pack("L", len(data))+data)
browser code浏览器代码
import socket #for sockets handling
import time #for time functions
import sys
import cv2
import pickle
import numpy as np
import struct ##
hostIP = '127.0.0.1'
SourcePort = 8082 #client socket
PlayerPort = 8081 #Internet Browser
def gen_headers():
# determine response code
h = ''
h = 'HTTP/1.1 200 OK\n'
# write further headers
current_date = time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime())
h += 'Date: ' + current_date +'\n'
h += 'Content-Type: image/jpeg\n\n'
return h
def start_server():
socketFFMPEG = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# this is for easy starting/killing the app
socketFFMPEG.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print('Socket created')
### new
data = b""
payload_size = struct.calcsize("L")
try:
socketFFMPEG.bind((hostIP, SourcePort))
print('Socket bind complete')
except socket.error as msg:
print('Bind failed. Error : ' + str(sys.exc_info()))
sys.exit()
#Start listening on socketFFMPEG
socketFFMPEG.listen(10)
print('Socket now listening. Waiting for video source from client socket on port', SourcePort)
conn, addr = socketFFMPEG.accept()
ip, port = str(addr[0]), str(addr[1])
print('Accepting connection from ' + ip + ':' + port)
socketPlayer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socketPlayer.bind((hostIP, PlayerPort))
socketPlayer.listen(1) #listen just 1 petition
print('Waiting for Internet Browser')
conn2, addr2 = socketPlayer.accept()
#conn2.sendall(gen_headers().encode())
while True:
try :
while len(data) < payload_size:
data += conn.recv(4096)
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0]
while len(data) < msg_size:
data += conn.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
###
frame=pickle.loads(frame_data)
#send data to internet browser
print(frame)
ret, frame = cv2.imencode('.jpg', frame)
frames = frame.tobytes()
conn2.sendall( gen_headers().encode()+frames)
except socket.error:
print('Error data :' + str(frame))
print('send Error : ' + str(sys.exc_info()))
conn2.close()
sys.exit()
socketFFMPEG.close()
start_server()
Server.py服务器.py
# This is server code to send video frames over UDP
import cv2, imutils, socket
import numpy as np
import time
import base64
BUFF_SIZE = 65536
server_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,BUFF_SIZE)
host_name = socket.gethostname()
host_ip = '192.168.1.102'# socket.gethostbyname(host_name)
print(host_ip)
port = 9999
socket_address = (host_ip,port)
server_socket.bind(socket_address)
print('Listening at:',socket_address)
vid = cv2.VideoCapture(0) # replace 'rocket.mp4' with 0 for webcam
fps,st,frames_to_count,cnt = (0,0,20,0)
while True:
msg,client_addr = server_socket.recvfrom(BUFF_SIZE)
print('GOT connection from ',client_addr)
WIDTH=400
while(vid.isOpened()):
_,frame = vid.read()
frame = imutils.resize(frame,width=WIDTH)
encoded,buffer = cv2.imencode('.jpg',frame,[cv2.IMWRITE_JPEG_QUALITY,80])
message = base64.b64encode(buffer)
server_socket.sendto(message,client_addr)
frame = cv2.putText(frame,'FPS: '+str(fps),(10,40),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)
cv2.imshow('TRANSMITTING VIDEO',frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
server_socket.close()
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
st=time.time()
cnt=0
except:
pass
cnt+=1
Client.py客户端.py
# This is client code to receive video frames over UDP
import cv2, imutils, socket
import numpy as np
import time
import base64
BUFF_SIZE = 65536
client_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client_socket.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,BUFF_SIZE)
host_name = socket.gethostname()
host_ip = '192.168.1.102'# socket.gethostbyname(host_name)
print(host_ip)
port = 9999
message = b'Hello'
client_socket.sendto(message,(host_ip,port))
fps,st,frames_to_count,cnt = (0,0,20,0)
while True:
packet,_ = client_socket.recvfrom(BUFF_SIZE)
data = base64.b64decode(packet,' /')
npdata = np.fromstring(data,dtype=np.uint8)
frame = cv2.imdecode(npdata,1)
frame = cv2.putText(frame,'FPS: '+str(fps),(10,40),cv2.FONT_HERSHEY_SIMPLEX,0.7,(0,0,255),2)
cv2.imshow("RECEIVING VIDEO",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
client_socket.close()
break
if cnt == frames_to_count:
try:
fps = round(frames_to_count/(time.time()-st))
st=time.time()
cnt=0
except:
pass
cnt+=1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.