音视频编解码:VP8 / VP9 / H.264 / Opus
WebRTC 支持哪些音视频编解码器?各有什么优缺点?怎么选?码率怎么设?这篇讲 WebRTC 常用的视频编码(VP8/VP9/H.264/AV1)和音频编码(Opus/G.711),对比选型、码率配置、以及编码相关的优化。
大家好,我是黒漂技术佬。
原始音视频数据量巨大,1080P 30帧的视频,一秒钟就要几百兆,根本没法传。所以要编码压缩——用更少的数据量,尽量保留画质。
WebRTC 支持多种编解码器,视频有 VP8、VP9、H.264、AV1,音频主要是 Opus。选哪个?码率设多少?有什么区别?
这篇讲 WebRTC 的音视频编解码,从原理到选型到配置。
一、为什么需要编解码?
原始数据量有多大?
以 1080P 30帧的视频为例:
- 每帧像素:1920 × 1080 ≈ 200 万像素
- 每个像素 YUV420:1.5 字节
- 每帧大小:~3MB
- 每秒 30 帧:~90MB/s = 720Mbps
720Mbps 的带宽,家用宽带上行一般只有几 Mbps,完全传不了。
编码压缩后
H.264 编码 1080P 30帧,一般 2-4Mbps 就够了,压缩了几百倍。
音频同理,原始 PCM 48kHz 16bit 立体声是 1536kbps,Opus 编码后语音只要 32kbps 左右。
二、视频编解码器对比
1. VP8
- 出品:Google(收购 On2 后开源)
- 定位:WebRTC 默认视频编码
- 特点:
- 免版税,不用交钱
- 兼容性好,所有浏览器都支持
- 编码速度快,低延迟
- 压缩率中等
2. VP9
- 出品:Google,VP8 的下一代
- 特点:
- 免版税
- 压缩率比 VP8 高 30-50%(同画质码率更低)
- 支持更高分辨率(4K)
- 编码复杂度高,CPU 占用大
- 兼容性比 VP8 差一点(现在主流浏览器都支持了)
3. H.264 / AVC
- 出品:MPEG 组织
- 定位:业界最通用的视频编码标准
- 特点:
- 硬件支持好,手机电脑都有硬编硬解
- 压缩率不错,和 VP8 差不多或略好
- 有专利,商用可能涉及授权费(WebRTC 里用一般不用操心)
- 兼容性最好,所有设备都支持
4. AV1
- 出品:AOMedia(Google、Netflix、微软等联合)
- 定位:下一代开放视频编码
- 特点:
- 免版税
- 压缩率比 VP9/H.264 再高 30%+
- 编码特别慢(软件编码 CPU 占用爆炸)
- 硬件支持还在普及中
- WebRTC 支持度逐渐完善
对比表
| 编码 | 免版税 | 压缩率 | 速度 | 硬件支持 | WebRTC兼容性 | 适用场景 |
|---|---|---|---|---|---|---|
| VP8 | ✅ | 一般 | 快 | 一般 | 最好 | 默认、兼容优先 |
| VP9 | ✅ | 好 | 中 | 一般 | 好 | 省带宽、画质优先 |
| H.264 | ❌ | 好 | 快 | 很好 | 很好 | 移动端、硬件加速 |
| AV1 | ✅ | 很好 | 慢 | 普及中 | 逐渐支持 | 未来、超高清 |
怎么选?
通用场景
- VP8:兼容性最好,编码快,默认选择
- H.264:移动端硬件加速好,省电,适合移动场景
带宽敏感 / 画质优先
- VP9:同码率画质更好,或者同画质省带宽
- 适合网络不好、或者想要更高清的场景
未来方向
- AV1:压缩率最高,但编码慢,硬件支持还不够
- 适合点播、直播等预编码场景,实时通信还不太普及
三、音频编解码器对比
1. Opus
- 出品:Xiph.Org + Mozilla
- 定位:WebRTC 默认音频编码
- 特点:
- 免版税
- 音质好,低码率下也不错
- 码率范围大:6kbps ~ 510kbps
- 低延迟
- 语音和音乐都擅长
- 所有浏览器都支持
WebRTC 音频首选,基本没有争议。
2. G.711 (PCMU/PCMA)
- 传统电话用的编码
- 码率固定 64kbps
- 音质一般,只适合语音
- 优点:极低复杂度,兼容性极好
- 和传统电话系统对接的时候用
3. G.722
- 宽带语音,音质比 G.711 好
- 码率 64kbps
- 也是老标准,主要用于兼容
对比
| 编码 | 码率 | 音质 | 延迟 | 适用 |
|---|---|---|---|---|
| Opus | 6-510kbps 可调 | 很好 | 低 | 通用首选 |
| G.711 | 64kbps 固定 | 一般 | 极低 | 电话对接 |
| G.722 | 64kbps | 较好 | 低 | 兼容场景 |
结论:音频就用 Opus,不用想。
四、码率怎么设置?
视频码率参考
| 分辨率 | 帧率 | 推荐码率 | 最低码率 |
|---|---|---|---|
| 320×240 | 15 | 150kbps | 100kbps |
| 640×480 | 24 | 500kbps | 300kbps |
| 640×480 | 30 | 750kbps | 400kbps |
| 1280×720 | 30 | 1.5Mbps | 800kbps |
| 1920×1080 | 30 | 3Mbps | 1.5Mbps |
| 1920×1080 | 60 | 5Mbps | 3Mbps |
只是参考,实际看场景:
- 会议/通话:可以低一点,动的少
- 游戏/运动:要高一点,画面变化快
音频码率参考
| 场景 | 推荐码率 |
|---|---|
| 语音通话 | 32kbps |
| 高质量语音 | 48kbps |
| 音乐/立体声 | 128kbps |
| 高音质音乐 | 192-256kbps |
一般语音通话 32kbps 就够了,Opus 在这个码率音质很不错。
怎么设置码率?
方式 1:SDP 里改
修改 SDP 中的 b=AS 行,或者用 RTCP REMB 反馈。
方式 2:用 setParameters(推荐)
constsender=pc.getSenders().find(s=>s.track.kind==='video');constparameters=sender.getParameters();if(!parameters.encodings){parameters.encodings=[{}];}parameters.encodings[0].maxBitrate=1500000;// 1.5Mbpsawaitsender.setParameters(parameters);动态调整,网络好的时候调高,不好的时候调低。
五、编码协商(SDP 中的编解码)
怎么看用了什么编码?
建立连接后看 SDP,或者 chrome://webrtc-internals 里看。
怎么指定优先用某个编码?
修改 SDP,把想要的编码移到前面:
functionpreferCodec(sdp,codecName){// 找到视频媒体行,调整编码优先级// 把目标编码的 rtpmap 移到最前面// ...}或者用 SDP Semantics 的方式,比较复杂。一般默认协商的就够用。
编解码协商过程
- Offer 里列出自己支持的所有编码,按优先级排
- Answer 里从 Offer 的列表中选双方都支持的
- 最终用双方都支持、优先级最高的那个
所以想让对方用 H.264,就把 H.264 放 Offer 最前面。
六、Simulcast(多流联播)
是什么
发送方同时推多路不同分辨率/码率的视频流,接收方选最合适的一路看。
发送方 → 1080P(高码率) → 720P(中码率) → 360P(低码率) 接收方根据自己的网络和屏幕大小选一路为什么需要?
多人会议时,每个人网络不一样:
- 网络好的看高清
- 网络差的看低清,不卡
SFU 架构常用 Simulcast。
配置
pc.addTrack(videoTrack,stream);constsender=pc.getSenders()[0];constparameters=sender.getParameters();parameters.encodings=[{rid:'high',maxBitrate:1500000,scaleResolutionDownBy:1},{rid:'mid',maxBitrate:500000,scaleResolutionDownBy:2},{rid:'low',maxBitrate:150000,scaleResolutionDownBy:4}];sender.setParameters(parameters);同时发三路:原始、1/2、1/4 分辨率。
七、自适应码率
是什么
网络好的时候调高码率(画质好),网络差的时候调低(不卡)。
WebRTC 自带带宽估计(GCC),会自动调整码率,但也可以手动干预。
怎么做?
- 监听网络状态(丢包、RTT、带宽估计)
- 动态调整 maxBitrate
- 极端情况降低分辨率和帧率
配合编码切换
带宽特别差的时候,从 720P 降到 360P,帧率从 30 降到 15,保证通话不卡。
八、硬件编解码
硬编 vs 软编
| 软件编码(CPU) | 硬件编码(GPU/NPU) | |
|---|---|---|
| CPU占用 | 高 | 低 |
| 功耗 | 高(手机发烫) | 低 |
| 画质 | 可调,一般更好 | 取决于硬件 |
| 兼容性 | 好 | 看设备支持 |
移动端一定要硬编
手机上软编 720P 30帧,CPU 满载发烫还卡。硬编码省电又流畅。
H.264 的硬件支持最广泛,VP9 也逐渐有了。
WebRTC 会自动用硬件编码吗?
会的,浏览器会自动尝试硬件加速,能用上就用,用不上就软件编码。
九、常见问题
1. 为什么视频模糊?
- 码率太低了,调高 maxBitrate
- 分辨率太低了,检查采集分辨率
- 动态场景码率不够,运动多的画面需要更高码率
2. 为什么视频卡、延迟高?
- 网络不好,码率太高,降码率
- 用了 TURN 中继,延迟会高一些
- 编码复杂度太高(比如 VP9 软编),换 VP8/H.264
3. 移动端发热严重?
- 分辨率/帧率太高,降一点
- 用硬件编码,H.264 硬编比 VP8 软编省电
- 关闭不必要的处理
4. 不同浏览器编码不一样?
是的,各浏览器支持的编码有差异。SDP 协商的时候会选双方都支持的。
Chrome 支持 VP8/VP9/H.264/AV1,Safari 对 VP9 支持晚一些。
5. 可以强制用某个编码吗?
可以,修改 SDP 只保留想要的编码。但对方不支持的话就会失败。
十、选型建议
一对一视频通话
- 视频:VP8 或 H.264,720P 1.5Mbps
- 音频:Opus 32kbps
- 简单稳定,兼容性好
多人会议(SFU)
- 视频:VP8 Simulcast(三路)
- 音频:Opus
- 不同人看不同清晰度
低带宽场景
- 视频:VP9,压缩率高,省带宽
- 或者降低分辨率到 360P
- 音频:Opus 24kbps
移动端为主
- 视频:H.264,硬件加速好,省电
- 音频:Opus
高质量直播/录制
- 视频:VP9 或 H.264 High Profile
- 高码率,高分辨率
十一、本篇小结
- 原始音视频数据量巨大,必须编码压缩才能传输
- 视频编码:VP8(默认、兼容好)、VP9(压缩高、省带宽)、H.264(硬件好、通用)、AV1(未来)
- 音频编码:Opus 是首选,音质好、码率范围大、低延迟
- 码率设置:根据分辨率和帧率,720P 30帧大概 1.5Mbps
- Simulcast:同时发多路不同质量,接收方选合适的,多人场景常用
- 自适应码率:根据网络动态调整,保证流畅
- 硬件编码:移动端重要,省电省 CPU,H.264 支持最好
- 选型看场景:通用选 VP8,省带宽选 VP9,移动优先选 H.264
下一篇讲RTCDataChannel 数据通道:除了音视频,WebRTC 还能传任意数据。
我是黒漂技术佬。