使用 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?
我目前正在从事一个涉及使用 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?