音频编解码基础:PCM 与 Opus
音频编解码,说白了就是解决「声音怎么存、怎么传」的问题。我刚开始做音视频时,觉得编解码离自己很远,直到第一次调试回声问题,才发现不懂底层编码根本无从下手。
PCM:最原始的音频格式
PCM 是脉冲编码调制。它直接把模拟信号的波形,按固定频率采样、量化、编码。你可以把它理解成「音频的原始照片」,没有经过任何压缩。
PCM 有三个关键参数:
- 采样率:每秒采多少个点。常见的有 8000Hz(电话)、44100Hz(CD)、48000Hz(专业音频)。
- 位深:每个采样点用多少 bit 表示。16bit 最常见,24bit 用于录音棚。
- 声道数:单声道、双声道(立体声)、多声道。
举个例子,一段 10 秒的立体声 PCM 音频,采样率 44100Hz,位深 16bit:
数据量 = 44100 × 16 × 2 × 10 ÷ 8 = 1,764,000 字节 ≈ 1.68 MB
嗯,10 秒就 1.68MB,这还没算网络传输。所以实时通信里,直接用 PCM 是不现实的。
Opus:WebRTC 的默认选择
Opus 是目前实时通信领域最流行的音频编解码器。它由 Skype 和 Xiph.Org 联合开发,2012 年成为 IETF 标准(RFC 6716)。
Opus 有几个让我印象深刻的特点:
- 可变比特率:从 6 kbps 到 510 kbps,覆盖语音到高保真音乐。
- 低延迟:最低 5ms 的算法延迟,适合实时通话。
- 自适应:网络差时自动降码率,网络好时恢复质量。
WebRTC 里,Opus 是默认的音频编码器。你不需要手动配置,浏览器会自动协商使用它。
视频编解码基础:H.264、VP8、VP9
视频编解码比音频复杂得多。音频是 1 维信号,视频是 2 维 + 时间轴。你想想看,一帧 1080p 的原始图像,RGB 格式下需要 1920×1080×3 ≈ 6.2 MB。30 帧每秒就是 186 MB/s。这带宽,谁也扛不住。
所以视频编码的核心思路是:去掉冗余。
- 空间冗余:同一帧内,相邻像素颜色相近。用 DCT 变换、量化来压缩。
- 时间冗余:相邻帧之间,大部分区域没变化。用运动估计、帧间预测来压缩。
- 视觉冗余:人眼对亮度敏感,对色度不敏感。所以 YUV 420 格式把色度采样率砍一半。
H.264:最广泛使用的视频编码
H.264(也叫 AVC)是 2003 年发布的标准。它至今仍是 WebRTC 里兼容性最好的编码器。几乎所有浏览器、手机、摄像头都支持。
H.264 有几个关键概念:
- I 帧、P 帧、B 帧:I 帧是关键帧,独立解码;P 帧参考前面的帧;B 帧参考前后帧。
- NAL 单元:H.264 的数据以 NAL 单元组织。每个 NAL 单元有类型标识,比如 SPS、PPS、IDR。
- Profile 和 Level:Profile 决定编码工具集,Level 决定分辨率、帧率上限。WebRTC 常用 Baseline Profile 或 Constrained Baseline Profile。
VP8 和 VP9:Google 的开源方案
VP8 是 Google 收购 On2 后开源的编码器。VP9 是 VP8 的升级版,压缩率比 H.264 高 30%-50%。
WebRTC 里,VP8 和 VP9 都是可选编码器。Chrome 默认优先使用 VP8,Firefox 默认用 VP9。实际使用中,我建议:
- VP8:兼容性好,编码速度快,适合移动端和低端设备。
- VP9:压缩率高,但编码计算量大,适合桌面端和带宽受限场景。
我记得有一次做远程医疗项目,客户要求 720p 视频,但带宽只有 1.5 Mbps。用 H.264 勉强能跑,但画面马赛克严重。换成 VP9 后,同样码率下画质明显提升。不过 VP9 的编码延迟也高了,手机端发热明显。
分辨率与帧率
分辨率和帧率是视频质量最直观的两个参数。但很多人容易陷入「越高越好」的误区。
分辨率:不是越大越好
分辨率决定画面的精细度。常见的有:
| 名称 | 分辨率 | 宽高比 | 典型用途 |
|---|---|---|---|
| QVGA | 320×240 | 4:3 | 老式手机、IoT 设备 |
| VGA | 640×480 | 4:3 | 标清视频 |
| HD | 1280×720 | 16:9 | 高清视频通话 |
| Full HD | 1920×1080 | 16:9 | 高清直播、录播 |
| 4K | 3840×2160 | 16:9 | 专业视频、大屏显示 |
分辨率越高,数据量越大。1080p 的数据量是 720p 的 2.25 倍。在带宽有限的情况下,我宁愿用 720p 30fps,也不要 1080p 15fps。因为低帧率带来的卡顿感,比低分辨率更让人难受。
帧率:流畅度的关键
帧率决定画面的流畅度。常见的有:
- 15fps:勉强能看,适合低端设备或网络极差时。
- 24fps:电影标准,适合非实时场景。
- 30fps:实时通信的常用帧率,流畅度可接受。
- 60fps:非常流畅,适合游戏直播、体育赛事。
WebRTC 里,帧率是动态调整的。如果 CPU 负载高或网络差,浏览器会自动降帧率。你可以通过 RTCRtpSender.setParameters() 手动控制帧率上限。
RTCRtpEncodingParameters 设置多个编码层,比如 720p 30fps 为主层,360p 15fps 为降级层。这样网络波动时,接收端能平滑切换。
知识体系总览
下面这张图,把本章的核心知识点串起来了。你可以把它当作一个快速索引。
音频和视频的编解码,说到底都是在「质量」和「带宽」之间找平衡。PCM 质量最好但带宽爆炸,Opus 是实时通信的最优解。视频这边,H.264 兼容性最好,VP9 压缩率最高,但各有取舍。
嗯,这一章的内容就到这里。记住一句话:没有最好的编码器,只有最适合场景的编码器。