在当前数字化浪潮下,基于互联网的实时音视频通信已经成为越来越多互联网应用的标配。得益于互联网基础设施的日趋完善和优秀开源解决方案WebRTC的出现,音视频实时通信的开发门槛也降低很多。但音视频应用的技术和工程实现复杂度还是比较高的,有必要深入其中搞清楚实现的来龙去脉。本文基于webRTC框架对实时音视频通信的一些关键实现做一些讨论,但其原理是相通的并不局限于webRTC。
WebRTC实时音视频通信框架
从它的名字上也可以看出webRTC是作为web端的实时通信方案提出的,目前在google大力推动下已经成为主流浏览器的标配功能。基于图1的架构实现信令服务器,web APP就可以轻松获得音视频通信的能力。
上面的场景只是简单的P2P(点对点)两方的通信,如果要支持多方通信和克服实际网络环境中各类防火墙的挑战,通常会引入更多的服务器功能单元,比如MCU(Multipoint Control Unit),SFU(Selective Forwarding Unit)。如图2,增加了Media Server承担MCU/SFU等功能,增加Data Server承担媒体类的信息交互,这种架构下原来的点对点的去中心结构变成了星状的结构。
通信的双方有三类交互信息,根据信息各自的特点可以有不同的传输方式。其中,signaling plane信令通道webRTC并没有实现,预留好了控制接口。Data plane和media plane,webRTC提供了一套完备的方案。
信令(signaling plane):交互协商双方的音视频编解码能力,完成通信链路(data/media plane)建立所必需的信息和参数交互。
数据(data plane):交互双方非音视频类的信息,一般实时性要求不高。
媒体(media plane):交互音视频数据,实时性要求高。
三条通信通道各有各的角色,各自完成自己的任务。media plane的整个链路处理最为复杂,实时要求也最高。本文仅就media plane的视频流(video)在SFU架构下端到端处理过程做一个完整解剖,参考webRTC m79分支做了逻辑抽象,对其他非webRTC的视频处理系统也有参考意义。
WebRTC的视频流关键路径
视频从发送端摄像头采集到接收端显示器渲染,我们定义为一个端到端的处理过程。接下来描述的过程是典型的精简系统的处理过程,实际生产线上的处理过程有可能还会多一些额外步骤。一件事情如果能抓住它的主线,那这件事情就不会跑偏。
media plane的传输通道的协议栈如图3所示,ICE(Interactive Connectivity Establishment )用来防火墙穿透和链路连通性监测。DTLS(Datagram Transport Level Security)过程完成密钥的交换,是后续media加密的辅助过程,如果不加密可以跳过,浏览器是默认打开加密功能的。在经过ICE和DTLS两个辅助过程后,media最终在(S)RTP/(S)RTCP之上传输。我们重点关注在这个媒体信息的传输路径。接下来我们看一下视频画面是怎样流过端到端的,关键路径如图4所示。
按照视频画面的处理顺序我们逐步看一下每个步骤发生了什么事情
发送方向(采集端-媒体服务器)
video capture:webRTC提供了丰富的设备管理功能,可以根据摄像头的能力和业务需要订阅不同等级的视频输出,可以控制摄像头输出的分辨率和帧率。
video adapter:视频帧适配器,可以裁剪视频画面,降低/升高视频辨率或丢帧以改变输入到encoder的数据量。video adapter与encoder之间会有交互,两者配合可以控制编码器的码率输出。
encoder:编码器,webrtc使用了openh264开源实现。
RTP/RTCP packetizer:组包器,按照RTP/RTCP协议规范组包。
Pacer queue:发送队列,组包器输出的RTP包放入该队列中等待发送。
Pacer&prober:发包器&带宽探测器,发包器根据当前预估的带宽限制,往Transport平稳发包。带宽探测器用于探测当前网络带宽上限,探测包的发送跟当前发送的实际有效包速率有关。
Transport:网络传输模块,加密,端口复用等网络传输功能。
接收方向(媒体服务器-播放端)
Transport:网络传输模块,解密,de端口解复用等网络传输功能。
RTP/RTCP depacketizer:解包器,按照RTP/RTCP协议规范解包,。
Packet buffer:视频包缓存,和解包器一起负责RTP包的乱序和丢包处理。去掉RTP包头后,视频包会存入该buffer,每次来了新包都会检查当前的缓存里面是否已经可以构成完整的视频帧,如果完整则组成完整帧继续下一步的处理,否则则结束当前包的处理。
Frame queue:帧队列,负责缓存当前待解码的视频帧。
Decoder:解码器,负责视频帧解码。解码的开始时机考虑了网络抖动、编码器延迟、渲染延迟。
Video render:渲染器,视频渲染接口模块。
媒体服务器
媒体服务器的实现不在webRTC的范围内,但也有不少优秀的开源实现,比如Kurento/Jitsi/Janus/Srs/OWT等。为了更好的服务业务需求,更多的音视频解决方案公司打造自己的媒体服务器,将webRTC媒体流引入到自己的媒体解决方案中。以Kurento为例,介绍一下Media server上的视频流处理。图片来源https://www.kurento.org/kurento-architecture
Kurento Media Server的媒体处理流水线是基于GStreamer实现的,其模块化和可扩展性做的非常好。一路视频流根据不同的业务需求,可能经过不同复杂程度的处理。列举几类典型的处理流水。
Stream s1:媒体流做了个传输层的路由后直接出去,这时Media Server只是做了简单的路由。这也是很有意义的,很多公司的音视频专网或者SDN依赖于这样的功能,使得用户可以就近接入到音视频云端服务器。注:云端的媒体流路由方案很多,media server集成route功能是其中一种方式。
Stream s2:媒体流做了完整的编解码-转码的过程,这个过程对Media Server的考验就比较重了,需要消耗很多计算资源。转码的部分可能是不同编码的转换如H.265->H.264,也可以是同一codec的码率转换。
Stream s3:媒体流相对s2还做了更多的操作,比如图像增强、混流等,甚至更多。
三条流s1-s2-s3,复杂度逐级在上升,需要哪些处理完全取决于业务需求。参与处理的服务器节点可以是媒体网关,可以是媒体路由,可以是转码服务器,可以是录制服务器,或者多个功能的叠加。设计合理的架构、优秀的功能模块抽象与划分,做到功能易扩展、集群易扩容,这是优秀架构师的修炼目标。
总结
本文对webRTC框架下典型的视频流端到端处理做了一次梳理,对理解类似音视频处理方案多有裨益。音视频的系统好比我们的自来水系统,该文讲解了整个处理过程是怎样的,但是输水管道不同段不同时间有大有小,有的管道有时还漏水,怎样在这样的传输通道上高效的输水?怎样在复杂网络条件下的互联网上传输实时要求很高的音视频?webRTC还有很多法宝,比如拥塞控制、码率自适应、容错机制等等,这些控制模块计算感知当前的传输和计算资源情况(网络、CPU、时延等),实时控制关键路径上的模块做出调整,力求公平高效的传输音视频。
本人原创文章,首发在infoq
https://xie.infoq.cn/article/...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。