我正在尝试使用带有 aiohttp 的多部分流通过 http 流式传输 MJPEG 视频。
我有一个基于james4388 的 Gist 的实现。我目前正在尝试每 30 毫秒左右发送一个新的 JPEG 图像。对循环进行计时表明,await mpwriter.write(response, close_boundary=False)
通常需要 0.3 毫秒,但每 3-5 次需要 150-200 毫秒。这限制了我可以达到的最大帧速率,并将延迟引入我试图避免的流中。
使用的循环是
while True:
_, frame = wc.read()
if frame is None:
continue
with MultipartWriter('image/jpeg', boundary=boundary) as mpwriter:
result, encimg = cv2.imencode('.jpg', frame, encode_param)
data = encimg.tostring()
mpwriter.append(data, {
'Content-Type': 'image/jpeg'
})
await mpwriter.write(response, close_boundary=False) # 'Pauses' here once every 3-5 times
await response.drain()
我也尝试过使用BaseHttpServer。这在调用 时表现出相同的行为self.wfile.write(jpg.tostring())
。
我假设当底层缓冲区通过网络刷新时会发生这种暂停,尽管我response.drain()
在每个部分之后调用。每个 JPEG 帧(因此多部分流的每个部分)大小为 441kB,因此对于 30fps,我将发送 13MB/s 但目前我达到 5.3MB/s。这是在专用测试 LAN 连接上,所以我认为带宽不是问题(另一个使用 MJPEG 流的设备达到 >15MB/s)。
使图像尺寸更小(例如使用更高的压缩率)会增加我在命中块之前可以发送的帧数,但整个块仍然存在,我的吞吐量仍然只有 4.3MB/s。