如何像 Python 中的 ShoutCast 一样将 OpenCV 输出流式传输到浏览器?

问题描述 投票:0回答:1

我正在尝试在网络浏览器中显示 OpenCV 处理的视频,类似于 ShoutCast 的做法。我知道 ShoutCast 以某种方式通过 HTTP 协议执行此操作,但我不知道如何使其显示视频并加载页面,而不是不断加载直到处理完成。我还知道 ShoutCast 不会向流页面发送任何内容,因为当我启动开发人员工具时,不会定期发送任何内容,但时间不断增加,音乐不断播放。有谁知道我该怎么做?

我的测试代码:

import os
from flask import Flask, Response
import cv2
from utils.app_root_dir import app_root_dir

app = Flask(__name__)


def generate_frames():
    cap = cv2.VideoCapture(os.path.normpath(app_root_dir().joinpath("data/temp", "video-979257305707693982.mp4")))
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


@app.route('/video-stream')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame', status=None)


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

用于测试的ShoutCast Streams: 直播#1 直播#2

python opencv flask video-streaming shoutcast
1个回答
0
投票

@ChristophRackwitz 说 Flask 不适合视频流。这不是真的。 Flask 并不真正知道或关心你发送给客户端的内容。重要的是您可以以流式传输方式逐块发送内容。当然,Flask 使用生成器支持此操作:https://flask.palletsprojects.com/en/2.3.x/patterns/streaming/

我还知道 ShoutCast 不会向流页面发送任何内容,因为当我启动开发人员工具时,不会定期发送任何内容

不,那不是真的。数据通过单个 HTTP 连接连续传输。浏览器发出对流的请求。服务器发送它,并且不会停止。

有人知道我该怎么做吗?

是的,您需要从使用视频编解码器开始。现在您只是将一帧一帧编码为 JPEG。这不是很有效并且不能按原样工作。您需要 VP9 或 H.264 等视频编解码器来获取原始帧缓冲区并将其编码到流中。

接下来,您需要 mux 流式传输到容器中,例如 WebM/Matroska,它将保留所有计时信息以及其他信息,以便播放器可以实际播放解码的帧。

然后,只需将来自复用器的流按需提供给客户端即可。没有多部分,没有这些,只有流。

完成所有这些操作的最简单方法是从 Python 进程中执行 FFmpeg。将其配置为读取 RGBA 格式的原始帧(或从 OpenCV 获得的任何内容),然后输出视频。像这样的东西...

ffmpeg -f rawvideo -s:v 640x480 -r 30 -i - -c:v libvpx-vp9 -f matroska -

然后,只需将 STDOUT 从 FFmpeg 传输到客户端即可。

在您客户的网页上,就像......一样简单

<video src="/video-stream" autoplay muted></video>
© www.soinside.com 2019 - 2024. All rights reserved.