Python Flask отображает только один кадр из живого видео в браузере, который транслируется из OpenCV - PullRequest
2 голосов
/ 10 мая 2019

Я столкнулся со странной проблемой, так как она работала прошлой ночью, и, насколько мне известно, я не внес никаких изменений.Так что у меня есть потоковая передача opencv с моего raspberry pi через сокетное соединение с моей удаленной машиной.Затем я планирую передать это в колбу, чтобы отобразить ее на веб-странице, где пользователь может посмотреть прямую трансляцию.

client.py

import cv2
import io
import socket
import struct
import time
import pickle
import zlib

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('ec2 instance id', 8089))
connection = client_socket.makefile('wb')

cam = cv2.VideoCapture(0)

cam.set(3, 320);
cam.set(4, 240);

img_counter = 0

encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]

while True:
    ret, frame = cam.read()
    result, frame = cv2.imencode('.jpg', frame, encode_param)
#    data = zlib.compress(pickle.dumps(frame, 0))
    data = pickle.dumps(frame, 0)
    size = len(data)


    print("{}: {}".format(img_counter, size))
    client_socket.sendall(struct.pack(">L", size) + data)
    img_counter += 1

cam.release()

Теперь мой код получаетнемного грязно, я не лучший, когда дело доходит до питона.Я знаю, что этот код сокета ниже может быть разделен на другой класс и прочее.

server.py

from flask import Flask, render_template, Response
from flask import make_response
import cv2
import socket
import sys
import cv2
import pickle
import numpy as np
import struct ## new
import zlib
app = Flask(__name__)

@app.route('/')
def index():
    """Video streaming home page."""
    return render_template('index.html')


def gen():
    """Video streaming generator function."""
    HOST=''
    PORT=8089

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    print('Socket created')

    s.bind((HOST,PORT))
    print('Socket bind complete')
    s.listen(10)
    print('Socket now listening')

    conn,addr=s.accept()
    data = b""
    payload_size = struct.calcsize(">L")
    print("payload_size: {}".format(payload_size))
    while True:
        while len(data) < payload_size:
            print("Recv: {}".format(len(data)))
            data += conn.recv(4096)

        print("Done Recv: {}".format(len(data)))
        packed_msg_size = data[:payload_size]
        data = data[payload_size:]
        msg_size = struct.unpack(">L", packed_msg_size)[0]
        print("msg_size: {}".format(msg_size))
        while len(data) < msg_size:
            data += conn.recv(4096)

        frame_data = data[:msg_size]
        data = data[msg_size:]

        frame=pickle.loads(frame_data, fix_imports=True, encoding="bytes")
        frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
        #vc = cv2.VideoCapture(frame)
        #below I am looping through frame and converting them back to byptes
         so I can display them in the browser as an image 

        for data1 in frame:
            data1 = cv2.imencode('.jpg', frame)[1].tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' +data1+ b'\r\n\r\n')



@app.route('/video_viewer')
def video_feed():

    return Response(gen(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True, threaded=True)

Теперь, когда я запускаю их, мне отображается только одно изображение вместо постоянной подачи изображений.как я уже говорил, этот метод работал прошлой ночью.Я думаю, что что-то не так с моей петлей?for data1 in the frame:.Извиняюсь за плохо написанный код сокета.Любая помощь в правильном направлении будет принята с благодарностью.

вывод из колбы, как вы видите, как только первый кадр изображения получен, он создает новый запрос на получение, который останавливает прямую трансляцию

output from flask as you see once the first image frame is received it creates a new get request which stops the live feed

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...