Quart infinite/indefinite 流响应
Quart infinite/indefinite streaming response
我正在尝试基于 an old blog post 创建一个服务器(松散地)以使用 Quart 流式传输视频。
要将视频流式传输到客户端,看来我需要做的就是有一个 returns 帧生成器的路由。然而,实际上这样做会导致 socket.send() raised exception
的不断重复消息,并在客户端上显示损坏的图像。之后,服务器似乎不再响应进一步的请求。
使用来自原始 post 的更多灵感,我尝试返回 Response
(使用 return Response(generator, mimetype="multipart/x-mixed-replace; boundary=frame")
。)这确实会在客户端上显示视频,但一旦它们断开连接(关闭选项卡,导航到另一个页面等)服务器再次开始发送垃圾邮件 socket.send() raised exception
并且不响应进一步的请求。
我的代码如下。
# in app.py
from camera_opencv import Camera
import os
from quart import (
Quart,
render_template,
Response,
send_from_directory,
)
app = Quart(__name__)
async def gen(c: Camera):
for frame in c.frames():
# d_frame = cv_processing.draw_debugs_jpegs(c.get_frame()[1])
yield (b"--frame\r\nContent-Type: image/jpeg\r\n\r\n" + frame[0] + b"\r\n")
c_gen = gen(Camera(0))
@app.route("/video_feed")
async def feed():
"""Streaming route (img src)"""
# return c_gen
return Response(c_gen, mimetype="multipart/x-mixed-replace; boundary=frame")
# in camera_opencv.py
from asyncio import Event
import cv2
class Camera:
last_frame = []
def __init__(self, source: int):
self.video_source = source
self.cv2_cam = cv2.VideoCapture(self.video_source)
self.event = Event()
def set_video_source(self, source):
self.video_source = source
self.cv2_cam = cv2.VideoCapture(self.video_source)
async def get_frame(self):
await self.event.wait()
self.event.clear()
return Camera.last_frame
def frames(self):
if not self.cv2_cam.isOpened():
raise RuntimeError("Could not start camera.")
while True:
# read current frame
_, img = self.cv2_cam.read()
# encode as a jpeg image and return it
Camera.last_frame = [cv2.imencode(".jpg", img)[1].tobytes(), img]
self.event.set()
yield Camera.last_frame
self.cv2_cam.release()
原来是an issue with Quart itself.
在对 Quart 和 Hypercorn 进行了一轮错误修复后,发布的代码按预期运行(截至 2018 年 11 月 13 日。)
我正在尝试基于 an old blog post 创建一个服务器(松散地)以使用 Quart 流式传输视频。
要将视频流式传输到客户端,看来我需要做的就是有一个 returns 帧生成器的路由。然而,实际上这样做会导致 socket.send() raised exception
的不断重复消息,并在客户端上显示损坏的图像。之后,服务器似乎不再响应进一步的请求。
使用来自原始 post 的更多灵感,我尝试返回 Response
(使用 return Response(generator, mimetype="multipart/x-mixed-replace; boundary=frame")
。)这确实会在客户端上显示视频,但一旦它们断开连接(关闭选项卡,导航到另一个页面等)服务器再次开始发送垃圾邮件 socket.send() raised exception
并且不响应进一步的请求。
我的代码如下。
# in app.py
from camera_opencv import Camera
import os
from quart import (
Quart,
render_template,
Response,
send_from_directory,
)
app = Quart(__name__)
async def gen(c: Camera):
for frame in c.frames():
# d_frame = cv_processing.draw_debugs_jpegs(c.get_frame()[1])
yield (b"--frame\r\nContent-Type: image/jpeg\r\n\r\n" + frame[0] + b"\r\n")
c_gen = gen(Camera(0))
@app.route("/video_feed")
async def feed():
"""Streaming route (img src)"""
# return c_gen
return Response(c_gen, mimetype="multipart/x-mixed-replace; boundary=frame")
# in camera_opencv.py
from asyncio import Event
import cv2
class Camera:
last_frame = []
def __init__(self, source: int):
self.video_source = source
self.cv2_cam = cv2.VideoCapture(self.video_source)
self.event = Event()
def set_video_source(self, source):
self.video_source = source
self.cv2_cam = cv2.VideoCapture(self.video_source)
async def get_frame(self):
await self.event.wait()
self.event.clear()
return Camera.last_frame
def frames(self):
if not self.cv2_cam.isOpened():
raise RuntimeError("Could not start camera.")
while True:
# read current frame
_, img = self.cv2_cam.read()
# encode as a jpeg image and return it
Camera.last_frame = [cv2.imencode(".jpg", img)[1].tobytes(), img]
self.event.set()
yield Camera.last_frame
self.cv2_cam.release()
原来是an issue with Quart itself.
在对 Quart 和 Hypercorn 进行了一轮错误修复后,发布的代码按预期运行(截至 2018 年 11 月 13 日。)