在网页上实时视频编码和流媒体

Ock*_*ius 6 python video ffmpeg video-streaming http-live-streaming

我想在网页上显示实时网络摄像头视频流,我有一个工作草案.但是,我对性能不满意,并寻找更好的方法来完成这项工作.

我有一个连接到Raspberry PI的网络摄像头和一个简单的python-Flask服务器的Web服务器.使用OpenCV捕获网络摄像头图像并格式化为JPEG.之后,这些JPEG将被发送到服务器的一个UDP端口.到目前为止我所做的就像是自制的MJPEG(运动jpeg)流式传输.

在服务器端,我有一个简单的python脚本,可以连续读取UDP端口并将JPEG图像放在HTML5画布中.这足以创建对直播的感知.

问题:

  • 这压缩视频很少.实际上它不压缩视频.它只通过格式化为JPEG来减小帧的大小.

  • FPS很低,而且流的质量也不是那么好.

  • 这不是现在的主要观点,但UDP不是一种流式传输视频的安全方式.

  • 服务器忙于从UDP中选择图像.需要线程服务器设计.

备择方案:

  • 我之前使用过FFMPEG来转换视频格式,也可以预先录制视频.我想,有可能使用ffmpeg或avconv进行编码(比如H.264)和流媒体WebCam直播视频.(编码)

这适用于Raspberry PI吗?

  • VLC能够播放在网络上流式传输的实时视频. (流)

是否有任何媒体播放器嵌入HTML/Javascript来处理像VLC那样的网络流?

  • 我已经阅读了有关HLS(HTTP直播流)和MPEG-DASH的内容.

这些适用于这种情况吗?如果是的话,我应该如何使用它们?

有没有其他方法可以在网页上显示直播流?

  • RTSP是一种安全协议.

视频流中传输层协议的最佳实践是什么?

小智 3

我将尽力回答您列出的尽可能多的“问题”:

\n\n
\n

FPS 很低,而且流的质量也不是很好。

\n
\n\n

由于您使用的是 Flask,因此您可以使用非常强大的url_for关键字将流式传输的帧直接显示到 img 标签中。实现此目的的方法如下:
\n在网页上,添加<img src="{{url_for(\'video_feed\')}}"您希望流式传输 Feed 的位置。
\n在后端执行以下操作:

\n\n
def gen(camera):\n    frame = camera.read()\n    yield (b\'--frame\\r\\n\'\n    b\'Content-Type: image/jpeg\\r\\n\\r\\n\' + frame + b\'\\r\\n\\r\\n\')\n\n@app.route(\'/video_feed\')\ndef video_feed():\n    return Response(gen(), mimetype=\'multipart/x-mixed-replace; boundary=frame\')\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,img 标签将显示端点上video_feed存在的多部分类型的图像。因此,它会在您的情况下不断要求更新的零件(更新的框架)。
\n我发现这种方法相当快!

\n\n

致谢:Miguel Grinberg 的博客文章

\n\n
\n

目前这不是重点,但 UDP 并不是一种安全的视频流传输方式。

\n
\n\n

大多数视频流设备不会对其流式传输的视频进行加密,因为这样做的计算成本很高。因此,虽然您可能通过 HTTPS 连接到设备上的嵌入式 Web 服务器,并且可能必须登录设备才能控制它,但所有安全性都仅限于 \xe2\x80\x9c 控制平面。\xe2\x80\x9d视频本身几乎肯定会以未加密的方式传输。如果它符合开放标准,则可能通过 RTP/RTSP 或 HTTP Live Streaming (HLS) 发送。

\n\n

资料来源:关于安全流媒体视频的思考

\n\n
\n

服务器正忙于从 UDP 中选取图像。需要线程服务器设计。

\n
\n\n

使用上述方法,即使在流式传输视频时我也能够与服务器交互。使用 Flask 开发 Web 服务器,您可以添加threaded=True到您的app.run()调用,或者--with-threads如果您使用 Flask CLI。
\n您还可以将Gunicorn与geventeventlet结合使用,以进一步控制您的线程。

\n