python потоковое видео с использованием opencv и веб-сокета - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь написать python скрипт, который транслирует видео в браузер с помощью веб-сокета. Я использую opencv в качестве клиента для отправки фреймов через сокет и скрипт браузера, получая и отображая его в браузере. одиночное изображение отображается в браузере, но возникает проблема, когда потоковое видео не может отображаться в браузере. python flask работает нормально, но есть несколько проблем, поэтому я планировал использовать веб-сокет для отображения в браузере

код клиента отправляет фрейм на сервер, используя 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)

код браузера

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()  
...