音视频中的弱网对抗

0 阅读4分钟

音视频对抗弱网技术详解

背景

在网络条件不理想的情况下,如何保证音视频通话的相对流畅体验?本文主要想讨论这个问题

一、什么是弱网?

弱网是指网络条件较差的环境,通常表现为以下特征:

指标正常网络弱网
带宽稳定充足波动大、可用带宽低
延迟< 100ms> 300ms 甚至更高
丢包率< 2%5%~30% 甚至更高
抖动波动剧烈

弱网场景

  • 移动网络(地铁、电梯、地下室)
  • 跨国/跨地区通信
  • 网络拥塞(高峰时段)
  • WiFi 信号弱
  • 网损仪

二、核心对抗技术

1. FEC(前向纠错)

原理:发送端添加冗余数据,接收端根据冗余数据恢复丢失的包,无需重传。

原始数据:[A][B][C][D]
FEC 数据(异或):[A⊕B][C⊕D]

如果 [B] 丢失,可通过 [A][A⊕B] 恢复

这种方法优点在于不会增加额外的时延,适合实时的音频传输,因为音频的包本身比较小,不过对于带宽也会增加,丢包率太高(大于20%)也不可用。所以只能适用于有限场景,如果冗余的异或包也丢失了,就可能就无法恢复了


2. ARQ(自动重传请求、NACK)

Automatic Repeat Request

原理:接收端检测到丢包后,请求发送端重传。

发送端 → [1][2][3][4] → 接收端
              ↓ (3 丢失)
接收端 → [NACK:3] → 发送端
发送端 → [3] → 接收端

这种方法在于不会增加额外的带宽,基本任意的丢包都可以恢复,不过因为增加了重传了,可能会阻塞带来了网络时延。不过结合最大重传次数和超时处理,可以算是一个很不错的方案了


3. 自适应码率(ABR)

原理:根据网络状况动态调整编码码率。

// 伪代码示例,一般是带宽估计算法 + 码率控制
function adjustBitrate(networkQuality) {
  if (networkQuality.bandwidth < 500kbps) {
    setVideoBitrate(300kbps);
    setAudioBitrate(20kbps);
  } else if (networkQuality.bandwidth < 2000kbps) {
    setVideoBitrate(1000kbps);
    setAudioBitrate(40kbps);
  } else {
    setVideoBitrate(3000kbps);
    setAudioBitrate(64kbps);
  }
}

这个常见的算法有GCC, BBR, WebRTC内置的拥塞控制,一般都是检测可用的带宽、丢包率,网络抖动JitterBuffer,缓冲区的大小(实时音视频不看这个指标)。

4. 抖动缓冲(Jitter Buffer)

原理:在接收端缓存数据包,平滑网络抖动,按正确顺序和时机播放

网络到达:[1]---[3][2]-----[4]--->  (乱序、间隔不均)
Jitter Buffer 整理后:
播放输出:[1][2][3][4]  (均匀间隔)

这个对时延要求高的场景不可用,一般适用于点播的场景


5. 包丢失隐藏(PLC)

原理:当音频包丢失时,根据前后数据插值生成替代数据。

这个按照我理解有点像是丢包了,但是自己用前后两个数据来作为参考直接生成一个新的数据,有点类比于NVIDIA显卡的DLSS自动插帧的原理。接触不多,等有了解了,再补充


在未来,说不定有AI的算法介入有可能可以实现本地的部分数据推测出来,也是相当的有可能。

三、WebRTC 中的实现

WebRTC 内置了多种弱网对抗机制:

WebRTC 内置机制

  • NACK/PLI/FIR 反馈
  • GCC 拥塞控制
  • NetEq 音频处理(含 PLC)
  • 动态码率调整

五、性能监控与调优

关键监控指标

指标阈值告警说明
丢包率> 5%上行 + 下行
RTT> 300ms往返延迟
卡顿率> 2%播放卡顿时间占比
码率波动> 50%码率变化幅度

六、总结

对抗弱网没有银弹,需要根据场景组合使用多种技术:

技术延迟影响带宽开销适用丢包率
FEC< 20%
ARQ任意
自适应码率任意
抖动缓冲抖动场景
PLC音频丢包

最佳实践

  1. 实时监控网络质量
  2. 动态调整策略组合
  3. 根据场景、对音频和视频做出一定的取舍
  4. 优雅降级优于直接断开

参考资料