WebRTC 和 IP 摄像头的交互
过去的几个月中,越来越多的开发者希望获得如何连接WebRTC与IP摄像头的信息。解决这个问题通常需要大量对底层媒体协议细节的深入了解。此外,在创造“Demo”和实际产品之间的距离也很大。我们将在本文中介绍如何利用Kurento的媒体服务器来正确地实现它。WebRTC Media Gateways for media interoperability对于集成IP摄像头到WebRTC应用,首先需要实现
过去的几个月中,越来越多的开发者希望获得如何连接WebRTC与IP摄像头的信息。解决这个问题通常需要大量对底层媒体协议细节的深入了解。此外,在创造“Demo”和实际产品之间的距离也很大。我们将在本文中介绍如何利用Kurento的媒体服务器来正确地实现它。
WebRTC Media Gateways for media interoperability
对于集成IP摄像头到WebRTC应用,首先需要实现媒体交互。这意味着摄像头提供的媒体流需要和WebRTC编解码器和浏览器支持的格式兼容。这也意味着将IP摄像头吐出的内容翻译成WebRTC浏览器支持的内容。为了实现这一点,通常需要一个被称为WebRTC 媒体网关的技术。为了理解这样一个网关的工作,来看以下几点:
Most IP cameras available in the market (excluding exotic ones) publish media through any of these mechanisms:
市面上大部分的IP摄像头(国外产品除外)通过以下几种机制来发布media:
RTSP/H.264: 这类型的摄像头通常用于安防场合。它们使用RTSP协议来建立一个RTP媒体会话。换句话说,媒体传输时通过RTSP发生的信令基于plain(简单的)RTP。不同的摄像头厂商可能支持不同的RTP规格,但是就我看到的大部分摄像头而言,AVP是唯一可用的选项。在这些摄像头中,同样典型的,H.264是编解码器唯一的选项。
HTTP/MJPEG: 这类型摄像头使用HTTP流来signaling,传输,将一系列的JPEG图像编码为视频。这些摄像头的硬件相对更简单,只需要很少的资源来操作。这就是为什么他们被更多用在电池功耗或者在意负载的场合(如机器人,无人机等)。不足的是,它们的视频质量显著下降。
因此,为了实现WebRTC交互性,媒体网关要求执行如下图所示的媒体管理程序。网关首先要有可以说同一门语言(如RTSP/RTP或HTTP)的能力,其次是解码从摄像头收到的视频流(如H.264或MJPEG),然后重新将它编码成VP8格式(WebRTC最普遍的编码),最后使用WebRTC协议栈将其发送到WebRTC客户端。
图1:WebRTC媒体网关在RSTP/H.264-HTTP/MJPEG摄像头和WebRTC浏览器之间提供媒体交互性的通用方案。媒体信息(暗红线)需要恰当的协议和编解码器适配来将摄像头提供的格式转换成WebRTC客户端支持的格式。但是,这还不足以在真实的网络中工作,因为真实网络需要考虑浏览器提供的RTCP反馈来管理丢包和拥塞。这对于达到令人满意的QoE是非常重要的,因为不是所有的WebRTC网关都有能力对RTCP反馈提供恰当的终止语义。
Dealing with the network: making a production ready application.
媒体适配对于实现可工作的应用是不够的。你还需要管理真实网络是如何工作的。为了实现这一点,WebRTC协议栈使用SAVPF规格,最后一个’F‘ 表示“Feedback”。这个Feedback组成了图1场景描绘的RTCP包,它包含了可能影响质量的网络条件的信息,从WebRTC客户端发往网关。
如上所述,大部分IP摄像头仅支持AVP(没有’F‘),这意味着网关不能传送反馈给摄像头(如发生在很多SFU架构中的那样),但是需要完全控制它。用术语说就是,网关必须终结RTCP反馈。
这是非常重要的。你必须确信你使用的WebRTC网关是真实的,并且完全终结和为RTCP传输提供语义。当RTCP传输未被终结时,你能感受到的是毁灭性的QoS,基本上视频停滞了。
为了理解视频停滞的原因,让我们分析一下当网关没有终结两种简单的反馈RTCP包:PLI和REMB时发生了什么:
如果网关没有管理PLI RTCP包的能力,一旦网络发生丢包时,视频就会停滞。这是由于VP8编码器的工作方式。 它可能不会在长时间周期内(通常是分钟)产生关键帧。Every time a PLI packet is not managed by the gateway by generating a new key frame,WebRTC客户端将不能解码直到一个新周期的关键帧抵达(重申,这可能需要几分钟)。一些网关使用一些技巧来处理这个问题:以很高频率(如每隔两秒钟)产生关键帧,但是这会显著降低VP8 编解码器的视频质量,因为关键帧消耗掉了更多的带宽。
如果网关不管理REMB RTCP请求,并且不考虑任何的协商控制机制,网关将不会对VP8编码器要求降低比特率的拥塞控制命令做出响应。这意味着,一旦网关和WebRTC客户端之间的连接被堵塞,WebRTC浏览器将会被视频传输超负荷,相关的丢包也会发生,导致体验质量的进一步下降,然后视频停滞。
Doing it right with Kurento Media Server
Kurento媒体服务器工具箱可以灵活创造丰富的WebRTC媒体网关,编程语言可以使用Java或者JavaScript。对于Kurento媒体服务器的介绍,可以参见 文档。在Kurento实现WebRTC媒体服务器与IP摄像头的交互是简单且安全的。你只需要考虑三个方面:
Kurento 媒体服务器 PlayerEndpoint 支持从不同来源读取视频流,包括RTSP/RTP和HTTP/MJPEG。换句话说,PlayerEndpoint有能力管理对IP摄像头媒体的捕获。
Kurento 媒体服务器 WebRtcEndpoint 支持发布媒体流到WebRTC浏览器,提供对RTCP反馈的完全终结。这意味着,每次PLI包被收到时,WebRtcEndpoint 应该命令VP8编码器生成一个新的关键帧。这同时也意味着通过命令VP8编码器降低质量,来实现对REMB反馈和拥塞控制的响应。
Kurento 媒体服务器发挥“不可知媒体能力”,当两个不兼容的媒体元素互联时,所有适当的转换对开发者来说都是透明的。因此,连接PlayerEndpoint源到WebRtcEndpointsink,H.264/MJPEG到VP8的转码就会被执行。
图2:Kurento媒体服务器实现了一个WebRTC网关,可以支持RTSP/H.264和HTTP/MJPEG。仅仅几行代码实例化PlayerEndpoint和WebRtcEndpoint元素,然后将它们连接,就可以创建一个网关。Kurento媒体服务器的内部逻辑负责执行必要的编解码适配,以及RTCP反馈的管理,而不需要开发者去关注。
因此,如图2所示,创建WebRTC媒体网关来实现RTSP/H.264,HTTP/MJPEG摄像头与WebRTC的交互是简单的。实现这部分逻辑的JavaScript源代码如下:
var pipeline = ...//Use Kurento Client API for obtaining your pipeline.
//Create the PlayerEndpoint for receiving from the IP camera. HTTP and RTSP uris are supportd
pipeline.create("PlayerEndpoint", {uri: "rtsp://your.rtsp.address"}, function(error, playerEndpoint){
//Create the WebRtcEndpoint
pipeline.create("WebRtcEndpoint", function(error, webRtcEndpoint){
//If working with trickle ice, some code for candidate management is required here.
//Connect playerEndpoint to webRtcEndpoint. This connection activates the agnostic media
//capability and the appropriate transcodings are configured and activated.
playerEndpoint.connect(webRtcEndpoint, function(error){
//Media starts flowing ... enjoy
player.play(function(error){
});
});
});
});
如果你需要JavaScript的完整可用例程,可以访问 GitHub repository.
所有这些的亮点是向你的网关添加更多的能力,如视频记录甚至是内容分析,它们仍然是非常简单的,你只需要实例化相应的媒体元素并将它们连接到期望的媒体拓扑。这便是使用Kurento的优势:模块化。
你是否有使用Kurento实现WebRTC和IP摄像头交互的经验?欢迎分享给我们。
更多推荐
所有评论(0)