1. 课程导入
各位好,我是老周。做了快十年的实时通信,今天咱们聊聊WebRTC里最让人头疼的问题——丢包。
你想想看,视频通话时画面突然卡成PPT,声音断断续续像机器人,这种体验谁受得了?说白了,丢包就是实时通信的"头号杀手"。
1.1 实时通信中的丢包问题
丢包这事儿,本质上就是数据包在传输过程中"走丢了"。我遇到过最夸张的一次,某客户的跨国会议,丢包率直接飙到30%——画面基本没法看。
丢包的原因其实挺多的:
- 网络拥塞:高峰期带宽不够用,路由器直接扔包
- 无线信号干扰:Wi-Fi穿墙、4G信号不稳,丢包率能到5%-10%
- 链路抖动:跨国传输时,路由跳数多,丢包概率成倍增加
- 设备性能瓶颈:老旧路由器处理不过来,直接丢弃
1.2 丢包对QoE的影响
QoE(体验质量)这东西,用户嘴上不说,但心里门儿清。丢包对它的影响,我总结成三个维度:
| 丢包率 | 视频影响 | 音频影响 | 用户感受 |
|---|---|---|---|
| 0% - 1% | 几乎无感 | 几乎无感 | 流畅 |
| 1% - 3% | 偶尔马赛克 | 轻微杂音 | 可接受 |
| 3% - 5% | 画面卡顿、花屏 | 声音断续 | 烦躁 |
| 5% - 10% | 视频无法观看 | 听不清内容 | 直接挂断 |
| > 10% | 完全黑屏 | 无声 | 彻底放弃 |
为什么会这样?因为视频编码依赖帧间预测,丢一个关键帧(I帧),后面几十个P帧全废了。音频虽然容错率高,但连续丢包超过50ms,人耳就能明显感知。
1.3 WebRTC抗丢包技术全景图
WebRTC为了对抗丢包,搞了一套"组合拳"。我画了张图,帮你快速建立全局认知:
这张图我画了好几次才满意。你看,WebRTC的抗丢包体系分三大块:
1.3.1 前向纠错(FEC)
说白了就是"多穿件防弹衣"。发送端额外生成一些冗余包,接收端即使丢了一部分,也能靠冗余数据把原始数据拼回来。我习惯把FEC分成两种:
- ULP FEC:基于异或运算,简单粗暴,适合低丢包场景
- Flex FEC:更灵活,可以自定义保护哪些包,适合复杂场景
我的实战经验:FEC不是冗余越多越好。我曾经把FEC冗余度调到50%,结果丢包率是降了,但带宽占用翻倍,反而引发了更严重的拥塞。记住,FEC是"以带宽换延迟",要找到平衡点。
1.3.2 重传机制(NACK/RTX)
这个好理解——发现丢包了,告诉发送端"哥们儿,那个包再发一遍"。WebRTC用的是选择性重传,只重传真正丢失的包,不是全量重传。
但有个坑:重传依赖RTT(往返时延)。如果RTT超过200ms,重传的包到了也晚了,视频已经卡过去了。所以,NACK适合低延迟网络,高延迟场景得靠FEC。
1.3.3 码率自适应
这是"治本"的思路。既然网络不好,那就降低码率,从源头减少丢包。WebRTC的GCC(Google Congestion Control)算法会实时探测带宽,动态调整编码器输出码率。
我记得有一次,某客户在3G网络下做视频通话,丢包率15%。我建议开启SVC(可伸缩视频编码),把视频分成基础层和增强层。网络差时只传基础层,画面虽然模糊点,但至少不卡。用户反馈说"比之前强太多了"。