使用 Flask 进行 YUV 直播视频流

YUV live video streaming using Flask

我目前正在从事一个涉及使用 Raspberry Pi 的小型机器人汽车的项目。为了有效地使用 picamera(图像处理和实时网络流),我想使用 YUV420 格式(picamera 支持)。这允许我直接使用 Y 值进行图像处理,并将任何进一步的转换留给客户。

是否可以通过 Flask Response 对象(如此处 JPEG 所示:http://blog.miguelgrinberg.com/post/video-streaming-with-flask)快速流式传输此数组(使用 Python 生成器)?如果是这样,我知道我可以在 JavaScript 中将 YUV 数据转换为 RGB,然后将其绘制到 canvas,但是如何一次访问一帧 YUV 流?

如果有任何其他更有效的解决方案(同时坚持使用 Flask),我也想听听它们。带有 Python 生成器的 Flask Response 对 JPEG 网络流来说就像一个魅力。

查看 the picamera documentation and the blog post you've linked,您可以创建一个多部分响应,其中包含从相机捕获的 YUV420 帧流,代码如下:

def gen():
    with picamera.PiCamera() as camera:
      camera.start_preview()
      # Camera warm-up time
      time.sleep(2)

      while True:
        stream = io.BytesIO()
        camera.capture(stream, 'yuv')
        yield stream.getvalue()
        #perhaps add a time.sleep() here to enforce a constant framerate?

但是,这并没有解决客户端问题。因为您想使用 JavaScript 中的图像数据,而不是仅仅将其显示在 <img> 标记中,所以您需要使用 XMLHTTPRequest 从 JavaScript 中获取它,而 XMLHTTPRequest 不需要支持多部分响应(具体来说,Firefox used to and no longer does)。

更好的方法是使用 WebSocket, since then it would be easy to open a WebSocket connection from JavaScript, read each frame in turn (each frame being sent in its own WebSocket message), and perform the necessary image processing. But what about the server-side? Flask-Sockets 看起来可以解决问题,然后发送帧流看起来像这样:

@sockets.route('/stream')
def stream_socket(ws):
    with picamera.PiCamera() as camera:
      camera.start_preview()
      # Camera warm-up time
      time.sleep(2)

      while not ws.closed:
        stream = io.BytesIO()
        camera.capture(stream, 'yuv')
        ws.send(stream.getvalue())
        #perhaps add a time.sleep() here to enforce a constant framerate?