当前在网络浏览器中流式传输实时视频的最佳实践?

Posted

技术标签:

【中文标题】当前在网络浏览器中流式传输实时视频的最佳实践?【英文标题】:Current best practice to stream live video in web browser? 【发布时间】:2018-03-29 01:39:54 【问题描述】:

我们开发了一款通过 RTSP/UDP 流式传输 H.264/MPEG4/MJPEG 视频的 IP 摄像头产品。它有一个网络界面,目前我们使用 VLC Firefox 插件来允许在浏览器中查看实时 RTSP 流,但 Firefox 正在放弃对 NPAPI 插件的支持,因此目前这是一条死胡同。

相机本身是一个相对低功耗的 ARM SoC(想想 Raspberry Pi 级别),因此我们没有大量的备用资源来执行诸如在板上即时转码流等事情。

主要目的是从网络界面检查视频流是否正常工作,因此以某种其他格式/传输/流引擎流式传输新流(或对其进行转码)不如能够以某种方式播放原始流RTSP 直接流式传输。在常规使用中,视频通过 RTSP 流式传输到 VMS 服务器,因此无法更改。

在理想情况下,解决方案将是开源跨浏览器并发生在 html5 标记内,但如果它适用于一个或多个最流行的浏览器,我们将采用它。

我一直在这里和网络上阅读各种关于 HTML5 视频标签、WebRTC、HLS 等的勇敢新世界的内容,但还没有看到任何看起来像明智且完整的解决方案的东西'不涉及一些额外的转换/转码/重新流式传输,通常由一些半支持的框架或中间的额外服务器,这不是一个可行的解决方案。

我还没有找到关于将我们的流“转换”为whatever-html5-video-likes可能需要或不需要什么的正确描述,无论它只是围绕相同基本视频流的稍微不同的包装器,还是有很多开销,一切都不同。同样,尚不清楚是否可以在板载或什至使用 JS 在浏览器中实现转换。

标题的原因是,如果我们必须改变它的所有工作方式,我们不妨致力于做任何被认为是“最佳实践”并且尽可能合理地面向未来的事情,而不是一些权宜之计在下一轮浏览器更新/下一次 W3C 新闻稿之后,这可能无法正常工作......

我觉得在 2017 年似乎没有实现这一目标的明智方法有点令人失望(但也许并不奇怪)。

也许“最坏的做法”是更合适的术语......

【问题讨论】:

遗憾的是,如果您不想添加转码,并且想要针对浏览器,您将需要重新考虑您的来源。 WebRTC 或 MPEG Dash(通过 https)可能是最好的长期独立于平台的解决方案,但要支持您需要更新相机以提供该功能……充其量,VLC 是一个适合当时的组合,但不再支持 【参考方案1】:

您可以使用许多不需要转码的方法。

WebRTC

如果您使用的是 RTSP,那么您就可以通过 WebRTC 发送流。

WebRTC 使用 SDP 声明流,使用 RTP 传输这些流。设置 WebRTC 调用还需要其他一些层,但这些层都不需要特别昂贵的计算。大多数(全部?)WebRTC 客户端都将支持 H.264 解码,其中许多在浏览器中具有硬件加速功能。

开始使用 WebRTC 的最简单方法是首先实现浏览器到浏览器客户端。然后,您可以通过自己的实现更深入一层。

WebRTC 是我向您推荐的路线。 NAT 遍历(在大多数情况下)和 P2P 连接是内置的,因此您的客户不必记住 IP 地址。只需提供信号服务,您的客户就可以从任何地方直接连接到他们家中的相机。提供 TURN 服务器,即使两端都有防火墙,它们也能连接。如果您不想提供此类服务,它们是轻量级的,可以直接在相机上以您现在的模式运行。

带有<video>标签的HTTP渐进式分段MP4

这种方法比 WebRTC 简单得多,但与您现在所做的完全不同。您可以获取 H.264 流,并将其直接包装在 MP4 中,无需转码。然后,它可以在页面上的<video> 标签中播放。您必须在代码中实现适当的库,但这里有一个输出到 STDOUT 的 FFmpeg 示例,您可以通过管道将其传送给客户端:

ffmpeg \
  -i YOUR_CAMERA_HERE \
  -vcodec copy \
  -acodec copy \
  -f mp4 \
  -movflags frag_keyframe+empty_moov \
  -

其他...

在您的情况下,DASH 没有额外的好处。 DASH 旨在利用基于文件的 CDN 进行流式传输。您控制服务器,因此写出文件或以类似文件的方式处理 HTTP 请求是没有意义的。虽然您当然可以将 DASH 与 H.264 流一起使用而无需转码,但我认为这是在浪费您的时间。

HLS 大致相同。您的流与 HLS 兼容,但 HLS 由于编解码器缺乏灵活性而迅速失宠。 DASH 和 HLS 本质上是相同的机制...将一堆媒体片段写入 CDN 并创建一个播放列表或清单来指示它们的位置。

【讨论】:

谢谢,您至少阐明了各种 TLA 的状态。是我自己还是 WebRTC 主页完全没有真正解释任何有用的东西或提供“流一些视频”的基本实际示例? @JohnU WebRTC 非常复杂,而且文档很少,通常很糟糕。从这里开始:developer.mozilla.org/en-US/docs/Web/API/WebRTC_API#Guidesdeveloper.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols 再次感谢!这可能无法挽救我的理智,但至少你会延长它的消亡时间。【参考方案2】:

好吧,当我回到树莓派 3 时,我不得不做同样的事情。我们在 pi 上使用 ffmpeg 对其进行动态转码,并使用https://github.com/phoboslab/jsmpeg 流式传输 mjpeg。然后在浏览器/离子应用程序上播放。

var canvas = document.getElementById('video-canvas');
this.player = new JSMpeg.Player(this.button.url ,canvas: canvas);

我们在 Pis 上管理最多 4 个并发流,最小延迟

但是一旦我们迁移到 React Native,我们就在手机上使用了 RN VLC 包装器

【讨论】:

以上是关于当前在网络浏览器中流式传输实时视频的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

agora 和 mux 和有啥不一样?在颤动中流式传输实时视频的最佳方式是啥?

Microsoft Lync 视频流式传输到网络浏览器

仅使用视频标签实时流式传输到 HTML5(没有 webrtc)

使用 socket.io 流式传输网络摄像头

将实时 http 流式传输到 HTML5 视频客户端的最佳方法 [关闭]

MVC 视频流式传输到移动网络浏览器