最近在做WebRTC相关的移动端视频会议,看了一下相关文档和一些Demo,总结一下构建webRtc应用流程。
相关文档连接:
1.一篇不错的中文文档,好像网上好多demo都是基于这个的http://segmentfault.com/a/1190000000439103
2.htmlRock里也有一些Sample,http://www.html5rocks.com/en/tutorials/webrtc/basics/
通过这2篇文档的学习,基本就差不多了解了相关内容
最近在做WebRTC相关的移动端视频会议,看了一下相关文档和一些Demo,总结一下构建webRtc应用流程。
相关文档连接:
1.一篇不错的中文文档,好像网上好多demo都是基于这个的http://segmentfault.com/a/1190000000439103
2.htmlRock里也有一些Sample,http://www.html5rocks.com/en/tutorials/webrtc/basics/
通过这2篇文档的学习,基本就差不多了解了相关内容
本次实验使用windows平台,其他平台如html5、android、ios、linux、mac等思路大同小异,上一篇文章已经提及,在此不再赘述。
TURN的全称为Traversal Using Relays around NAT,是STUN/RFC5389的一个拓展,主要添加了Relay功能。如果终端在NAT之后,那么在特定的情景下,有可能使得终端无法和其对等端(peer)进行直接的通信,这时就需要公网的服务器作为一个中继, 对来往的数据进行转发。这个转发的协议就被定义为TURN。TURN和其他中继协议的不同之处在于,它允许客户端使用同一个中继地址(relay address)与多个不同的peer进行通信。
使用TURN协议的客户端必须能够通过中继地址和对等端进行通讯,并且能够得知每个peer的的IP地址和端口(确切地说,应该是peer的服务器反射地址)。而这些行为如何完成,是不在TURN协议范围之内的。其中一个可用的方式是客户端通过email来告知对等端信息,另一种方式是客户端使用一些指定的协议,如“introduction” 或 “rendezvous”,详见RFC5128
如果TURN使用于ICE协议中,relay地址会作为一个候选,由ICE在多个候选中进行评估,选取最合适的通讯地址。一般来说中继的优先级都是最低的。TURN协议被设计为ICE协议(Interactive Connectivity Establishment)的一部分,而且也强烈建议用户在他们的程序里使用ICE,但是也可以独立于ICE的运行。值得一提的是,TURN协议本身是STUN的一个拓展,因此绝大部分TURN报文都是STUN类型的,作为STUN的一个拓展,TURN增加了新的方法(method)和属性(attribute)。
随着移动设备大规模的普及以及流量的资费越来越便宜, 超低延迟的场景越来越多. 从去年到今年火过的场景就有在线娃娃机, 直播答题, 在线K歌等. 但要做到音视频的超低延迟确是很不容易, 编码延迟, 网络丢包, 网络抖动, 多节点relay,视频分段传输,播放端缓存等等都会带来延迟.
WebRTC兴起提供的方案以及遇到的问题
WebRTC技术的兴起为低延迟音视频传输带来了解决方案, 但WebRTC是为端到端设计的, 适合的场景是小规模内的实时互动, 例如视频会议, 连麦场景. 即使加入了SFU Media server作为转发服务器, 也很难做到大规模的分发. 另外一个需要考量的是流量成本, WebRTC的实时流量是通过UDP传输的(某些情况下可以用TCP), 无法复用在传统CDN的架构之上, 实时的流量价格更是CDN流量的3倍以上, 部署一个超低延迟的直播网络成本非常高.
RTMP系统推流播放延迟分析
一个经过优化的RTMP-CDN网络端到端的延迟大概在2-3秒, 延迟大一些要在5秒甚至10秒以上. 从推流到播放, 会引入延迟的环节有编码延迟, 网络丢包和网络抖动, 视频的分段传输, 多媒体节点的relay, 播放器的缓存等等. 实际上除了网络丢包和网络抖动不太可控之外, 其他的各各环节都有一定的优化方案, 比如使用x264的-preset ultrafast和zerolatency, 可以降低编码的延迟,
分段传输部分可以把GOP减少到1秒之内, 在播放器端可以适当减小buffer, 并设置一定的追帧策略, 防止过大的buffer引起的时延.
低成本的低延迟的实现
何为 WebRTC ?首先,字面上已经给出了关于这一技术的大量信息,RTC 即为实时通信技术。
WebRTC 填补了网页开发平台中的一个重要空白。在以往,只有诸如桌面聊天程序这样的 P2P 技术才能够实现实时通讯而网页不行。但是 WebRTC 的出现改变了这一状况。
WebRTC 本质上允许网页程序创建点对点通信,我们将会在随后的章节中进行介绍。我们将讨论如下主题,以便向开发者全面介绍 WebRTC 的内部构造:
每个用户的网页浏览器必须按照如下步骤以实现通过网页浏览器进行的点对点通信:
WebRTC音频引擎的实现代码主要分布在如下几个源码目录中:
webrtc/audio
webrtc/common_audio
webrtc/media/engine
webrtc/voice_engine
webrtc/module/audio_coding
webrtc/module/audio_conference_mixer
webrtc/module/audio_device
webrtc/module/audio_processing
WebRTC音频引擎的整体架构如图1所示。
众所周知,WebRTC的拥塞控制和码率估计算法采用GCC算法[1]。该算法充分考虑了网络丢包和网络延迟对码率估计的不同影响,分别基于丢包率和网络延迟进行码率估计,最后综合这另种码率得出最优值。在算法实现上,基于丢包率的码率估计在发送端进行,基于网络延迟的码率估计在接收端进行。最后在发送端计算出最优值,作用于Codec和PacedSender模块。GCC算法能够较好地基于网络实时状况估计网络带宽,为网络实时通信应用打下坚实基础[2][3][4]。
然而,随着时间推移,在实际测试中发现GCC算法逐渐显出一些弊端,比如不能适应所有网络模型,应对网络峰值能力差,等等。为此,Google官方从M55版本引进最新的拥塞控制算法Sendside-BWE,把所有码率计算模块都移到发送端进行,并采用全新的Trendline滤波器取代之前的Kalman滤波器[5]。实测表明,新的算法实现能够更好更快地进行码率估计和网络过载恢复。
本文基于WebRTC的M66版本和相关RFC,深度分析学习最新Sendside-BWE算法的实现。
2 GCC算法回顾
关于GCC算法已经有很多分析和论述[6][7],本文只回顾其算法框架,并分析其在实际应用中存在的问题。
getStats的标准由W3C定义,其接口很简单,但是却返回丰富的WebRTC运行时信息。其返回信息的主要内容如下[2]:<br />
另外还有一些杂项统计,如DataChannel度量,网络接口度量,证书统计等等。在众多信息中,有一些反映WebRTC运行状态的核心度量,包括往返时间RTT,丢包率和接收端延迟等,分别表述如下:<br />
通过以上分析可知,getStats的返回信息包含WebRTC数据管线的各个阶段的统计信息,从数据采集、编码到发送,再到数据接收、解码和渲染。这为监控WebRTC应用的运行状态提供第一手数据。<br />
WebRTC 自诞生之日起, 就代表了实时通信领域的最好的技术. 不过很长时间里, 它所支持的视频编码器只有VP8, 后来随着H265/VP9为代表的下一代视频编码器的诞生, WebRTC里出现了VP9 Codec. 而当前应用最广泛的H264 却一直不受待见. 一直到Cisco 宣布旗下的H264 Codec开源为OpenH264, 并且替所有OpenH264的使用者支付了H264的专利费, 以次为契机, 在IETF的WebRTC会议中, 把H264和VP8都列入了WebRTC所必需要支持的视频编码器。 接下来, Google终于在WebRTC中增加了对H264的支持, 在PC平台(Windows和MAC), 编码器是用OpenH264, 解码器是用FFMPEG, 在iOS平台上, 编码器和解码器既可以使用OpenH264和FFMPEG, 也可以用apple的VideoToolbox所支持的硬件编解码器. 在Android平台, 可以用 OpenH264, FFMPGE, 也可以用 MediaCodec. 这个对于广大需要H264的公司来说是一大福音. 在下载的WebRTC代码中做稍许配置, 就可以使用H264了.
最近实验了下如何让WebRTC支持H264编码,记录下,供有需要的人参考。
说明一下,我是在 Ubuntu Server 14.04 下编译的 WebRTC ,使用 native(C++) api 开发 WebRTC 应用。所以我的调整都是基于 native 代码。
最终的效果是浏览器可以用H264发送视频,也可以接收H264视频。
注意,WebRTC 使用 OpenH264 来做 encoder (见 h264_encoder_impl.cc),使用 ffmpeg 来做 decoder (见 h264_decoder_impl.cc )。
代码版本
本文对应的代码是2017年2月8号的,可以使用 gclient revinfo -a来查看具体版本,如下: