WebRTC与WebSockets服务器到客户端(一对多)从IP摄像机的实时视频流



我找不到确切的答案,假设我有一个服务器从IP摄像机接收RTSP馈送,这个流将广播到多个客户端,连接总是由客户端初始化。

我想知道在这种情况下,使用WebSockets而不是WebRTC来广播媒体流是否会更好,因为从我所看到的情况来看,WebRTC服务器实现无论如何都不支持媒体通道,所以我需要使用数据通道,并将流打包为与MediaSource兼容,以及配置信令、TURN和STUN服务器,当我可以使用WebSockets做同样的事情时,我是不是遗漏了什么,或者在这种情况下WebSockets真的会更好,比如WebRTC是否有任何功能可以让在WebSockets上实现它的开销变得值得?

编辑:忘记提到客户端是Web浏览器。

一些注意事项和其他需要考虑的事项:

…据我所见,webRTC服务器实现无论如何都不支持媒体通道,所以我需要使用数据通道…

可以在服务器端运行WebRTC媒体频道,但您是对的,因为可用于此操作的软件有限。实际上,我经常在服务器上使用无头Chromium,因为它很容易,但这不适用于您的用例,因为您的流是通过RTSP进入的。

如果您选择WebRTC路线,我建议在服务器端使用GStreamer。它对WebRTC所需的一切都有自己的实现。您可以使用它来获取您现有的流和多路复用器,并根据WebRTC的需要进行流和转码。

我可以使用WebSockets 做同样的事情

你可以,但我建议在这一点上只使用常规HTTP。您的流只是单向的,从服务器到客户端。不需要Web套接字的开销和麻烦。事实上,如果你做对了,你甚至不需要客户端有什么特别的东西。只是一个视频元素:

<video src="https://streams.example.com/your-stream-id" preload="none" controls></video>

服务器需要设置所有视频初始化数据,然后放入直播流中。客户端只会播放流,没有问题。

我使用了一个轻量级Node.js服务器,包装了FFmpeg。通过这种方式,从源中获取视频是微不足道的。当我这样做的时候,我实际上使用了WebM。第一个Cluster元素之前的所有数据都可以被视为初始化数据。然后,假设每个簇都以一个关键帧开始(通常是这样),您可以稍后放入流的任何部分。(另请参见:https://stackoverflow.com/a/45172617/362536)

换句话说,从FFmpeg获取WebM/Matroska输出并缓冲它,直到您看到0x1F43B675。在此之前,请将其作为初始化数据保留。当客户端连接时,发送初始化数据,然后启动";活的";一旦看到下一个0x1F43B675,就立即流式传输。(这是一个让你开始的快速摘要,但如果你在实施中遇到困难,请发布一个新问题。)

现在,你该怎么办

这归结为一些权衡。

  • 如果需要端到端低延迟(<2秒),则必须使用WebRTC
    整个堆栈虽然很复杂,但围绕着尽可能低的延迟构建。在编码、解码、网络和任何地方都会进行权衡。这意味着更低的媒体质量。这意味着,当数据包丢失时,会尽一切努力跳过客户端,而不是缓冲以获取丢失的数据。但是,如果您需要低延迟,所有这些都需要完成。

  • 如果您想要最简单的实现,每个源拥有大量客户端或想要使用现有的CDN并且不介意更高的延迟,请考虑HLS
    每个源只需一个简单的FFmpeg命令,您就可以一直运行所有输入的实时流,当客户端连接时,它们只会接收播放列表和媒体片段。这是一种将源端与服务端和客户端隔离开来的好方法,并允许您重用大量现有的基础设施。当然,缺点是增加了延迟,而且确实应该让源流一直运行。否则,在最初启动流时将有相对较长的延迟。此外,HLS可以很容易地为您提供自适应比特率,只需花费更多的CPU进行代码转换。

  • 如果每个源有几个客户端并且不需要ABR,请考虑HTTP渐进式流媒体代理
    这基本上可以是一个大约10行的Node.js服务器,它接收来自客户端的流请求。当收到请求时,它会立即执行FFmpeg连接到源,然后FFmpeg输出WebM流。这与我上面所说的类似,但由于每个客户端都有一个单独的FFmpeg进程,因此不需要缓冲直到Cluster元素或其他内容。只需将FFmpeg输出直接管道传输到客户端即可。这实际上可以让您获得相当低的延迟。我已经将其降低到约300ms的玻璃到玻璃延迟。不利的一面是,如果数据包丢失,客户端肯定会尝试缓冲,然后就会落后。通过查看缓冲的时间范围并决定是寻找还是提高播放速度,您可以始终跳过播放器前置客户端。(这正是HLS玩家在直播落后太多时所做的。)除此之外,客户端只是一个视频元素。

这是一个非常宽泛的主题,因此希望这个答案能为您提供更多的选择,以便您能够决定什么最适合您的特定用例。没有一个正确的答案,但肯定有一些权衡,既有技术性的,也有易于开发的。

最新更新