WebRTC应用可能出现的网络错误

作者:Anton Venema(原文链接

翻译:刘通

 

为什么一个视频通话在某个环境下可以进行的很流畅,但是换了个网络环境就会变得很差?为什么一个音频通话一直在正常运行,却突然一下终端了呢?

network-problems1

有些是时候造成这些问题的原因是程序中存在bug。特别是安卓,简直臭名昭著,经常出现程序在一个设备上可以完美运行,但是换到另一个设备就崩溃的情况。

与iOS不同,iOS是的软件和硬件都是依据严格的标准,由同一家厂商一并设计而出的;而对于安卓来说,有很多不同的硬件和软件级别,由多个厂家设计,所以有的时候会导致没有预料到的奇怪错误出现。这个问题严重影响了应用软件适用于哪些只能手机,以及软硬件的适用范围。

而有些情况,这些问题是由较差的网络环境造成的,也就是可能有一个或者多个参数超过了我们设定的“好”的范围。如果你遇到了有的设备运行软件正常,有的设备运行出问题这种状况,那么你需要检查一下这几个参数:

# 带宽

# 延时

# 丢包

# 抖动

 

带宽

带宽是指数据可以在两个端点之间传输的速率。

你可以将你和远端之间的网络看成一个管道,而带宽就是这个管道最小的尺寸。你的网速可以特别的快,但是如果对方连入的是一个WiFi热点或者企业VPN,只有几KB/s的速度的话,你的网速再快也没有用。

如果一个不受控制的发送端所发送数据的速率超过了接收端的可用带宽,那么它就会迅速压垮整个网络,导致数据流质量产生严重的恶化。一个过载的连接会出现以下几种问题:

# 永久的视频停止

# 永久的视频帧速率降低

# 断断续续的音频

# 连接性能下降

如果你遇到了这几个问题,可以用fast.com或者speedtest.net这两个网址来测试带宽大小。

在你的应用中,你可以简单的从服务器下载一个大的文件,然后观察一两秒之内能下载多少,来快快的进行一个带宽测试。虽然做法很简单,但是是十分有效的。

因为连接是活跃的,所以最好的解决方法是,发送方通过使用RTCP回馈来尽可能准确的估计接收方的可用带宽。IceLink将RTCP数据作为它API的一部分展示出来,使应用可以实时的调整媒体流以适应他们的需求。

 

延时

延时值得是数据从一个网络端口传输到另一个端口所花费的时间(通常以毫秒为单位)。

往返时延(RTT)与延时密切相关,因为它是数据从一个网络端口传输到另一端再传回来的时间。如果x是A到B的延时,y是B到A的延时,那么RTT就是x+y。

视频通话的主要延时是听见音频和看见视频方面上的延迟。一个小的延时(不超过100ms)并不会在双端通话之间被察觉到。如果数据流是一个单向的音频广播,那么甚至较为严重的延时也不会造成多大的问题。

而视频完全就是另一种情况了。

一个高效的视频流很大程度上依赖于,出现丢包的时候接收端发回给发送端的被动应答(NACK)。发送端有机会重发丢失的数据包,避免重发一个完整的帧刷新。

一个高延时的网络会极大的降低网络的效率,因为RTT可能会远远的超过接收端可等待的时间范围。为了确保食品的音画同步性,接收端只能最多等待音频缓冲区那么长的时间。音频通常不会被这种情况影响,因为音频并不依赖于关键帧。

一个高延时的连接可能造成:

# 音视频的延时

# 短暂的视频停顿

# 短暂的视频帧速率下降

# 平滑的音频

 

丢包

丢包是指,在一段时间内数据包在数据流中被丢弃或者丢失的数量或者百分比。

大多数的媒体流都会或多或少地丢弃一些数据包,尤其是在WiFi网络的环境下。在一个实时媒体流中,宁愿让连接的设备主动丢弃掉一些数据/帧,也不愿意产生延时。

如何处理丢包是由发送数据本身决定的。如果前向纠错(FEC)被启用,那么有时就可以通过已接收到的数据来自动恢复丢失的数据。

如果FEC不可用的话,那么智能的音频编码器(比如Opus)可以利用播放的波形来产生一个接近丢失音频包的近似波形—这项技术被称为丢帧隐藏(PLC)。

在音频编码器不支持PLC技术,或者丢包率实在太高的情况下,会产生空的数据包来填补丢失的空洞。这就会导致音频的中断,但是会让播放缓冲随时准备好接收接下来传递的数据。

尽管音频包可以通过NACK和重传机制来修复,但是通常来讲在实时媒体通信中不推荐这么做,因为:

#1 接收到被修复的数据包的时候已经太晚了,而无法使用(时间不等人)

#2 因为音频已经处于一个很低的比特率的状态,NACK请求会很大比例地增加音频所占带宽

#3 除非丢包率很高(这种情况下NACK可能也无法起到作用),音频的中断不会长到对会话产生影响

#4 与视频不一样,对数据包的恢复是立刻产生的,不需要关键帧。

视频丢包通常情况下使用前文所提到的NACK进行处理,因为要进行一个全帧刷新的网络消耗是在是太大了。

如果NACK失败了的话,我们就没有其他的选择了,只能发送一个PLI来进行请求。

通常,在良好的网络情况下,适当的丢包并不会被觉察到。如果丢包率较高的话就会引起一下问题:

# 经常的视频暂停

# 经常的视频帧速率下降

# 断断续续的音频

如果你查看你的IceLink日志,通常会看到发出了很多课NACK,有可能还会有一些涂销丢失标识(PLI),以及很多产生的PLC。

如果丢包率很高而且恢复机制无法弥补的话,视频就会卡住,帧速率会下降,声音会因为经常断续而变得难以辨识。如果与高延迟网络相结合,丢包就会造成最严重的影响,会影响到基于NACK的重传机制的效率。

如果本质原因是过载的网络设备,那么解决方法就是降低比特率,这会降低对网络的需求。

当WiFi网络十分拥挤或者与邻近网络产生干扰的时候,丢包这类问题会经常出现。

 

抖动

抖动是一项用来描述网络流中时间稳定性的参数。换句话说,数据包实际到达的时间与应该到达的时间之间的间隔是多大。

因为UDP并不能保证传输的有序性,抖动会发生在每个连接中。每次网络路径上的传递都可能会发生抖动,所以高延时网络或者跳跃次数多的网络更有可能出现高抖动值的问题。

因为媒体解码器/播放模块必须按顺序处理数据包,所以如果在收到数据包之后立即就进行处理的话就会出现问题。

一旦一个数据包被解码器进行处理时,任何“之前的”数据包就必须被丢弃掉。这很容易造成丢掉可以增加音频质量或者进行重传视频的重要数据。

要想消除抖动的影响就需要媒体接收端通过一个“抖动缓冲区”(jitter buffer)来处理数据。

抖动缓冲区的作用是对蒸菜接收处理的媒体数据包进行适当的延迟,以达到可以平滑输出的目的,并且确保数据包处在一个正确的顺序中。更大的延迟值会更好的消除网络抖动,但会给传输带来更大的延时。因为每次通话的网络状态可能差别很大,所以不同情况下的最佳抖动缓冲区也就不一样:需要根据需要来增加或者减少延迟。

假设抖动缓冲区可以快速的适应网络状态的改变,高的抖动值会造成:

# 突发的视频卡住

# 突发的视频帧速率下降

# 突发的音频断续

这些问题与丢包造成的问题很相似,但是可以通过抖动缓冲区来解决。查看你的IceLink日志,你应该可以看到抖动缓冲区大小的增加/减少来适应不同的网络需求。

 

填写常用邮箱,接收社区更新

WebRTC 中文社区由

运营