【问题标题】:Streaming multiple videos with Flask?使用 Flask 流式传输多个视频?
【发布时间】:2020-09-22 03:00:47
【问题描述】:

要使用flask 进行视频流式传输,this linkthis link 都建议使用generator 进行流式传输。以下是我流式传输一个视频的工作示例。 但我的问题是:如何同时流式传输多个视频?

我的文件夹结构如下:

root_folder/
    templates/
        index.html
    server.py
    video1.mp4
    video2.mp4

server.py

Camera 类读取视频文件并转换为.jpeg 格式。路由'/video_feed/<index>' 指向分配有index 的视频源。

import cv2
from flask import Flask, render_template, Response

app = Flask(__name__)


class Camera:
    def __init__(self, index):
        self.path = f'video{index}.mp4'
        self.cap = cv2.VideoCapture(self.path)

    def get_frame(self):
        while 1:
            success, image = self.cap.read()
            # to replay video infinitely
            if not success:
                print('replay')
                self.cap = cv2.VideoCapture(self.path)
                success, image = self.cap.read()

            _, encoded = cv2.imencode(".jpg", image)

            yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
                  bytearray(encoded) + b'\r\n')


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/video_feed/<index>')
def video_feed(index):
    return Response(Camera(index).get_frame(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    app.run(debug=True)

index.html

<img src="{{ url_for('video_feed', index='1') }}">
<!--<img src="{{ url_for('video_feed', index='2') }}">-->

当只有一个img 标签要求视频源时,这非常有用。但是如何同时流式传输多个视频?当我取消注释另一个 img 标签时,前端卡住了。流没有播放,CPU 使用率飙升。

我想我完全搞砸了。我的代码怎么了?

在普通的 python 程序中(不使用烧瓶),我会使用多进程或线程处理多个视频。但是,我对烧瓶中的线程概念感到困惑,无法弄清楚如何实现。

感谢任何建议。谢谢!

【问题讨论】:

    标签: python flask


    【解决方案1】:

    我不是 Falsk Guru,但在遇到同样的问题后,我的唯一想法是:

    1. 为您的流添加一个标识符,例如:
        @app.route('/video/<vid_id>.html')
        def render_video(vid_id):
            return render_template('pages/video_stream.html', name=vid_id)
    
    1. 然后,在您的 video_stream.html 中,您可以执行img.src = '/video_feed/' + {{name}} 之类的操作

    ** 我认为你需要先将名称存储在一个JS变量中,然后使用该变量

    1. 现在,在提供帧时,您可以将 Flask 路由到正确的生成器,如下所示:
        @app.route('/video_feed/<vid_id>')
        def video_feed(vid_id):
            print("Feeding video %s" % vid_id)
            # Do whatever
    
    1. 无论哪种方式,我都看不到如何避免全局变量从字符串映射到实例的需要。

    2. 此外,我不知道如何轻松地垃圾收集视频流媒体。

    • 一种方法是让 JS 在关闭窗口之前发送一条消息,这似乎不是一个值得信赖的方法
    • 另一种是存储最后发送帧的时间戳,手动kill。
    1. 说了这么多,我仍然在努力让 Flask 继续为 JS 提供图像,当我停止 img 刷新计时器时(所以浏览器中的视频停止了,但 Flask 热情地继续向任何人发送图像)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 2016-09-24
      • 2016-01-15
      • 1970-01-01
      相关资源
      最近更新 更多