WebRTC 的编解码器:VP8、VP9、H.264、AV1 对比与协商
聊到 WebRTC,编解码器是个绕不开的话题。说白了,视频通话能不能流畅、清晰,很大程度上取决于你选了什么编码器。我这些年做过的项目里,因为编解码器踩过的坑,真不算少。
今天咱们就把 VP8、VP9、H.264、AV1 这四位主角拉出来,好好对比一下。顺便聊聊它们是怎么在浏览器之间「握手」的——也就是编解码器协商。
为什么需要多种编解码器?
你可能会问:一个编码器不够用吗?嗯,还真不够。
不同的场景,对编码器的要求不一样。比如:
- 实时性要求高:视频会议,延迟要低,编码速度要快。
- 带宽有限:移动网络,码率要省,画质还不能太差。
- 兼容性优先:老设备、老浏览器,得能跑起来。
没有哪个编码器能同时做到最好。所以 WebRTC 支持多种编码器,让两端自己商量着来。
四大编解码器速览
先给个总览表格,方便你快速对比:
| 编码器 | 推出时间 | 专利情况 | 压缩效率 | 浏览器支持 | 硬件加速 |
|---|---|---|---|---|---|
| VP8 | 2008 | 开源免费 | 中等 | Chrome, Firefox, Edge | 有限 |
| VP9 | 2013 | 开源免费 | 较高 | Chrome, Firefox, Edge | 较广泛 |
| H.264 | 2003 | 需授权 | 中等 | 几乎所有浏览器 | 非常广泛 |
| AV1 | 2018 | 开源免费 | 最高 | Chrome, Firefox, Edge | 有限(较新设备) |
核心观点:没有「最好」的编码器,只有「最合适」的编码器。选型时,要综合考虑兼容性、性能、带宽和功耗。
逐个拆解:VP8、VP9、H.264、AV1
VP8:WebRTC 的元老
VP8 是 WebRTC 最早支持的编码器之一。我记得 2012 年刚接触 WebRTC 时,Chrome 和 Firefox 之间通话,默认就是 VP8。
它的优点很明显:
- 免费:没有专利授权问题,随便用。
- 实现简单:编码器代码量小,解码快。
- 浏览器支持好:Chrome、Firefox、Edge 都原生支持。
但缺点也突出:
- 压缩效率一般:同等画质下,码率比 H.264 高 20%-30%。
- 硬件加速少:大部分手机芯片没有 VP8 硬编硬解,全靠 CPU 扛。
我的经验:如果你做的是纯软件方案,或者目标设备性能足够强,VP8 是个稳妥的选择。至少不会遇到专利麻烦。
VP9:Google 的进阶之作
VP9 是 VP8 的升级版。Google 推出它,就是为了跟 H.265 竞争。压缩效率比 VP8 提升了 30%-50%。
我曾在项目中用 VP9 做过 1080p 的视频会议。同等码率下,画面确实比 VP8 干净不少。但代价是编码复杂度高,CPU 占用率飙升。
适用场景:
- 带宽受限:比如移动网络,想省流量。
- 设备性能好:有足够的 CPU 或 GPU 资源。
- 屏幕共享:VP9 对静态画面压缩效果特别好。
注意:VP9 的编码器在低端手机上可能会卡顿。我曾经在某个项目里,因为用了 VP9,导致老款 Android 手机发热严重,最后不得不切回 H.264。
H.264:兼容性之王
H.264 是视频编码界的「老黄牛」。从 2003 年到现在,几乎所有设备都支持它。浏览器、手机、摄像头、电视盒子……你几乎找不到不支持 H.264 的设备。
为什么 WebRTC 也支持 H.264?
- 硬件加速普及:几乎所有手机芯片都有 H.264 硬编硬解,省电又高效。
- 兼容性最好:跟非 WebRTC 系统对接时,H.264 是通用语言。
- 生态成熟:各种编码器、解码器、转码工具一应俱全。
但 H.264 有个绕不开的问题:专利授权。虽然浏览器厂商已经帮你付了授权费,但如果你自己做商业产品,可能需要考虑专利风险。
我的建议:如果你的产品需要跟大量第三方设备互通,优先选 H.264。兼容性带来的好处,远大于那点压缩效率的差距。
AV1:未来的希望
AV1 是新一代开源编码器,由开放媒体联盟(AOM)推出。压缩效率比 VP9 和 H.265 还要高 20%-30%。
但 AV1 目前最大的问题是:编码太慢。软件编码器在实时场景下,基本跑不动。我试过用 AV1 做 720p 的实时编码,CPU 直接拉满,延迟飙到 500ms 以上。
不过,硬件加速正在赶来。2023 年之后的新款手机芯片(比如骁龙 8 Gen 2、苹果 A17)开始支持 AV1 硬解码。编码方面,还需要再等一两年。
适用场景(目前):
- 点播场景:非实时,可以离线编码。
- 未来规划:等硬件编码器成熟后,AV1 会是 WebRTC 的终极选择。
编解码器协商:SDP 与 Offer/Answer 模型
好了,了解了四种编码器,接下来聊聊它们是怎么「商量」出用谁的。
WebRTC 使用 SDP(Session Description Protocol) 来协商编解码器。流程很简单:
- 发起方(Offerer)生成一个 SDP Offer,里面列出自己支持的编码器列表。
- 接收方(Answerer)收到 Offer 后,从列表里选一个自己支持的编码器。
- 双方确认后,开始用选定的编码器传输数据。
这个过程,就是经典的 Offer/Answer 模型。
SDP 中的编解码器描述
在 SDP 里,编码器是通过 m= 行和 rtpmap 属性来描述的。举个例子:
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99
a=rtpmap:96 VP8/90000
a=rtpmap:97 VP9/90000
a=rtpmap:98 H264/90000
a=rtpmap:99 AV1/90000
这段 SDP 的意思是:
- 视频流使用端口 9,传输协议是 UDP/TLS/RTP/SAVPF。
- 支持四种编码器:VP8(96)、VP9(97)、H.264(98)、AV1(99)。
- 每个编码器后面跟着时钟频率(90000),这是 RTP 的标准值。
接收方收到后,会从 96、97、98、99 里选一个自己支持的。比如选 98(H.264),然后回复 SDP Answer。
协商优先级
你可能会问:如果两端都支持多个编码器,到底选哪个?
答案是:按 Offer 里的顺序。Offer 里排在前面的编码器,优先级更高。接收方会优先选择自己支持的第一个编码器。
所以,如果你想让两端优先用 H.264,就把 H.264 放在列表最前面:
m=video 9 UDP/TLS/RTP/SAVPF 98 96 97 99
a=rtpmap:98 H264/90000
a=rtpmap:96 VP8/90000
a=rtpmap:97 VP9/90000
a=rtpmap:99 AV1/90000
小技巧:在实际项目中,我经常根据场景动态调整编码器优先级。比如在移动端,把 H.264 放前面;在桌面端,把 VP9 或 AV1 放前面。
编解码器协商的常见问题
协商过程看起来简单,但实际项目中坑不少。我挑几个常见的说说:
1. 编码器不支持
有时候,浏览器声称支持某个编码器,但实际编码时却失败了。比如 Safari 对 H.264 的支持很好,但对 VP8 的支持就有限。
解决办法:在建立连接前,先通过 RTCRtpSender.getCapabilities() 检查浏览器实际支持的编码器。
2. 编码器参数不匹配
即使两端都支持 H.264,但参数可能不一样。比如 H.264 的 Profile(Baseline、Main、High)不同,或者 Packetization Mode 不同。
我曾经遇到过一个坑:Chrome 默认用 H.264 Constrained Baseline,但某个硬件编码器只支持 Main Profile。结果视频就是出不来。
解决办法:在 SDP 里明确指定编码器参数,比如:
a=fmtp:98 profile-level-id=42e01f;packetization-mode=1
3. 编码器协商超时
如果两端支持的编码器完全没有交集,协商就会失败。比如一端只支持 VP8,另一端只支持 H.264。
解决办法:在应用层做 fallback。比如先尝试 H.264,如果失败,再尝试 VP8。或者干脆用转码服务器做中转。
SVG 流程图:编解码器协商过程
下面这张图,展示了完整的编解码器协商流程:
如何在实际项目中选择编码器?
说了这么多,最后给点实战建议。我个人习惯这样选:
- 通用场景:H.264 优先。兼容性最好,硬件加速最普及。
- 纯 Web 端:VP8 或 VP9。省去专利烦恼,浏览器支持好。
- 高画质需求:VP9 或 AV1。但要注意设备性能。
- 未来规划:逐步引入 AV1。等硬件编码器成熟后,它会成为主流。
避坑指南:我曾经在一个项目中,为了追求画质,强制所有客户端都用 VP9。结果老款 iPhone 直接黑屏——因为 Safari 不支持 VP9 硬解码。从那以后,我学乖了:永远要留一个 fallback 编码器。
好了,关于编解码器的对比和协商,就聊到这里。记住一句话:没有银弹。理解每种编码器的优缺点,根据场景灵活选择,才是正道。