音频编解码:Opus、AAC 与延迟权衡

Opus 与 AAC 是当代音频分发的两大主力,但它们的适用边界完全不同。本文拆解 Opus 的 SILK/CELT 混合架构、AAC-LC 与 HE-AAC 的频带复制、帧长与算法延迟的换算、CBR/VBR/CVBR 码率控制、丢包隐藏与 FEC,并给出 WebRTC 与流媒体的选型、协商和 WebCodecs 实战。

引言

音频编解码器决定了"用多少比特描述一段声音"。有损编码的核心不是"压缩波形",而是利用听觉掩蔽效应丢弃听不到的信息:把信号分解到频带,按心理声学模型计算每个频带的掩蔽阈值,允许低于阈值的量化噪声任意大。理解这一点,才能理解为什么同样 128 kbps,不同编解码器的听感差异巨大。

工程上选编解码器要同时权衡四个维度:码率(带宽成本)、延迟(交互体验)、抗丢包(网络质量)、兼容性(终端覆盖)。Opus 在延迟与码率上全面领先,AAC 在兼容性与硬件解码上占优,MP3 只剩兼容老设备的价值。

本文先建立感知编码的基本模型,再分别拆解 Opus 与 AAC 的架构,然后讨论帧长与延迟的换算关系、码率控制模式、丢包隐藏与前向纠错,最后给出选型、协商与浏览器端(WebCodecs)的落地方法。

目录

  1. 有损编码的感知模型
  2. Opus 架构:SILK 与 CELT 的混合
  3. AAC 家族:LC、HE 与 xHE
  4. 帧长、码率与算法延迟
  5. 比特率控制:CBR、VBR 与 CVBR
  6. 丢包隐藏与前向纠错
  7. 编解码器选型与协商
  8. 浏览器中的编解码:WebCodecs
  9. 质量实测与评估方法

1. 有损编码的感知模型

感知编码的三块基石:

  • 临界频带(Critical Band):人耳对频率的分辨率不是线性的,低频分辨率高(约 100 Hz),高频分辨率低(可达 4 kHz)。编码器按临界频带划分频带,而不是均匀划分。
  • 频域掩蔽:一个强音会掩蔽邻近频带的弱音。掩蔽阈值随频率距离衰减,典型为 10~25 dB/临界频带。
  • 时域掩蔽:强音前后的短时间窗内,弱音也被掩蔽(前掩蔽约 520 ms,后掩蔽约 50200 ms)。

编码器的量化噪声不需要"低于信号",只需要低于掩蔽阈值。这就是为什么有损编码能做到 10:1 甚至 20:1 的压缩而听感接近无损。

每频带分配比特数 ≈ f(信号能量 - 掩蔽阈值)
掩蔽阈值高的频带 → 少分配比特甚至不编码

心理声学模型的实现差异(频带划分、掩蔽曲线、时域扩散函数)直接决定了编码器在同等码率下的听感。这也是 AAC 在同码率下普遍优于 MP3 的根本原因——MP3 的模型是第一代,AAC 是第二代。

2. Opus 架构:SILK 与 CELT 的混合

Opus(RFC 6716)是 IETF 标准,2012 年发布,完全免专利费。它的独特之处在于同时包含两种编码模式并按信号动态切换:

  • SILK:源自 Skype 的语音编码器,基于线性预测(LPC),面向 8/12/16/24 kHz 的语音,擅长低码率(6~40 kbps)。
  • CELT:源自 Xiph 的 Constrained Energy Lapped Transform,基于 MDCT,面向音乐与宽带信号,擅长 32 kbps 以上的高保真。

2.1 模式切换

编码器每帧(2.5~60 ms)决定用 SILK、CELT 还是混合模式(SILK 编低频 + CELT 编高频)。切换由内部信号分析驱动,对调用方透明。

语音(低码率)        → SILK
音乐 / 宽带(高码率)  → CELT
混合内容(16~32 kbps) → SILK + CELT 混合

2.2 关键参数

参数取值范围说明
采样率8/12/16/24/48 kHz内部可重采样
帧长2.5/5/10/20/40/60 ms越短延迟越低
码率6~510 kbps单声道 6~256,立体声到 510
声道1~2支持联合立体声、双声道
复杂度0~10越高越慢,质量越好
# 用 opusenc 编码:48 kHz、20 ms 帧、64 kbps VBR
opusenc --bitrate 64 --framesize 20 --vbr input.wav out.opus

# 强制 CELT 模式(音乐)
opusenc --hard-cbr --bitrate 128 --framesize 20 music.wav out.opus

# 解码
opusdec --force-wav out.opus out.wav

2.3 为什么 WebRTC 强制 Opus

  • 延迟最低:2.5 ms 帧长下算法延迟约 5 ms,加上前后处理也只有十几毫秒。
  • 码率自适应范围宽:同一编解码器从 6 kbps 到 510 kbps 全覆盖,网络波动时无需换编码器。
  • 内置 FEC 与 DTX:前向纠错与静音抑制都是标准的一部分。
  • 免专利:WebRTC 的强制编解码(与 VP8/AV1 同属免专利阵营)。

网络拥塞控制如何驱动码率切换,见 webrtc-codec-congestion-control 。

3. AAC 家族:LC、HE 与 xHE

AAC(Advanced Audio Coding,ISO/IEC 13818-7)是 MPEG 标准,1997 年发布,广泛用于流媒体、广播与 Apple 生态。

规格全称核心技术典型码率延迟
AAC-LCLow ComplexityMDCT + 量化96~256 kbps中
HE-AAC v1High EfficiencyLC + SBR32~96 kbps中高
HE-AAC v2HE-AAC + PSv1 + 参数立体声16~48 kbps中高
AAC-LDLow Delay短窗 MDCT64~128 kbps低
xHE-AACExtended HEUSAC12~64 kbps中高

3.1 SBR 与 PS

**SBR(Spectral Band Replication)**不编码 8 kHz 以上的高频,而是只编码低频并传少量"如何重建高频"的边信息。解码器用低频成分谐波外推生成高频。这能在低码率下保留"明亮感",代价是高频细节是合成的,对某些素材(镲片、弦乐泛音)听感不自然。

**PS(Parametric Stereo)**把立体声降成单声道 + 少量空间参数(ILD、ICLD、ICC),解码时重建立体声像。它在极低码率下效果显著,但立体声分离度会下降。

3.2 AAC 的帧结构

AAC-LC 的标准帧长是 1024 个样本(长窗),外加 2048 点的 MDCT 重叠。在 48 kHz 下:

1024 / 48000 = 21.33 ms(帧长)
加上 MDCT 重叠与编码器前瞻 → 算法延迟约 40~60 ms

AAC-LD 用 512 点窗,算法延迟可压到约 20 ms,代价是低频分辨率下降。这就是为什么实时会议若必须用 AAC 会选 LD 变体。

3.3 专利与许可

AAC 的核心专利多数已过期(最早一批 1997 年申请,2017 年前后到期),但 Via LA 等专利池仍对部分实现收取许可费。这是 WebRTC 选择 Opus 而非 AAC 的原因之一。

4. 帧长、码率与算法延迟

算法延迟(algorithmic delay)由编码器结构决定,与网络延迟无关。它是"采集到可发送"与"收到到可播放"的时间。

总算法延迟 = 编码器前瞻 + 帧长 + 解码器缓冲 + 重采样
编解码器帧长算法延迟(编码+解码)
Opus @ 2.5 ms2.5 ms~5 ms
Opus @ 20 ms20 ms~26 ms
Opus @ 60 ms60 ms~70 ms
AAC-LC1024 样本4060 ms
AAC-LD512 样本~20 ms
MP31152 样本5070 ms

4.1 帧长与码率的权衡

短帧长带来低延迟,但每帧的头部开销与变换效率损失使同码率质量下降:

48 kbps @ 20 ms 帧 → 每帧 960 bit = 120 字节
48 kbps @ 2.5 ms 帧 → 每帧 120 bit = 15 字节

15 字节里还要放帧头与模式信息,留给频谱数据的极少。因此低延迟与高压缩率不可兼得:交互场景用 20 ms 帧,非交互场景用 60 ms 帧换取更好质量。

4.2 端到端延迟中的位置

算法延迟只是端到端延迟的一小部分。以 20 ms 帧的 Opus 为例,一次往返的拆解大致为:

采集缓冲     5 ms
编码         20 ms(帧长)+ 5 ms(前瞻)
网络         30 ms
抖动缓冲     40 ms
解码         5 ms
播放缓冲     10 ms
─────────────────────
合计        约 115 ms

抖动缓冲往往是可优化的最大项,详见 audio-streaming-latency 。

5. 比特率控制:CBR、VBR 与 CVBR

模式行为适用
CBR每帧固定字节数实时传输、固定带宽信道
VBR按内容复杂度分配比特离线编码、存储
CVBR有上限的 VBR(约束 VBR)流媒体、码率上限明确
ABR平均码率约束长时间尺度平均

5.1 实时场景为什么用 CBR

实时传输中,码率突变会导致发送队列积压或抖动缓冲水位波动。CBR 让每帧大小可预测,网络调度简单。代价是简单段落浪费比特、复杂段落质量下降。

5.2 Opus 的码率控制细节

# 硬 CBR(每帧字节数严格相等)
opusenc --hard-cbr --bitrate 64 in.wav out.opus

# 约束 VBR(允许波动但有上限)
opusenc --vbr --bitrate 96 --comp 10 in.wav out.opus

# 开启 DTX(静音段不发送)
opusenc --dtx in.wav out.opus

--comp 控制复杂度(010),越高越慢但质量越好。移动端通常设 57 平衡功耗。

5.3 码率与质量的拐点

经验数据(48 kHz 立体声,Opus):

码率主观质量
24 kbps可懂但明显失真(语音可接受)
48 kbps语音良好,音乐一般
96 kbps接近透明(多数素材听不出)
160 kbps透明
256 kbps+边际收益极小

AAC-LC 的拐点略高:约 128 kbps 接近透明,192 kbps 透明。HE-AAC 在 48 kbps 下优于 AAC-LC,但在 128 kbps 以上反而不如 LC(SBR 的合成高频成为负担)。低码率用 HE-AAC,高码率用 AAC-LC 是基本原则。

6. 丢包隐藏与前向纠错

丢包对音频的影响远大于视频:视频丢一帧只是画面卡顿,音频丢一帧是"啪"或静音。

6.1 PLC(Packet Loss Concealment)

丢包隐藏不是恢复数据,而是合成一段听起来连续的替代信号:

  • 语音:用最近的基频与频谱包络外推,保持音高连续。
  • 音乐:重复上一帧的频谱并衰减,或做时域淡出。

Opus 的 PLC 质量在同类中领先,能掩盖 5~10% 的随机丢包而主观上不明显。

6.2 FEC(Forward Error Correction)

Opus 支持带内 FEC:在每个包中携带上一帧的低码率副本。接收端丢包时用副本重建。代价是码率增加约 20~30%。

启用 FEC 后每包结构:
[当前帧数据][上一帧的低码率冗余副本]

6.3 重传与 NACK

WebRTC 默认启用 NACK(Negative Acknowledgement):接收端发现序号空洞就请求重传。重传在 RTT 小于抖动缓冲深度时有效(例如 RTT 40 ms、缓冲 80 ms),否则来不及。FEC 与 NACK 通常同时开启,由拥塞控制器动态决定 FEC 比例。

7. 编解码器选型与协商

7.1 场景矩阵

场景首选备选理由
实时通话Opus 20 msG.722、AAC-LD低延迟 + 抗丢包
实时音乐(Jam)Opus 5~10 ms—延迟优先
点播流媒体AAC-LC 128~256Opus、Vorbis硬件解码普及
低码率流媒体HE-AAC v2Opus广播兼容性
语音助手Opus 16 kHzAMR-WB免专利、算力低
归档FLACALAC无损

7.2 协商机制

WebRTC 用 SDP 协商编解码与参数。Opus 的参数通过 a=fmtp 行传递:

a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate=32000;stereo=0

useinbandfec=1 开启带内 FEC,minptime=10 表示最小打包间隔 10 ms(即 10 ms 帧长),maxaveragebitrate 限制平均码率。SDP 协商的完整流程见 webrtc-sdp-negotiation 。

8. 浏览器中的编解码:WebCodecs

WebCodecs 提供了对编解码器的直接访问,绕开容器与 <audio> 标签。

const decoder = new AudioDecoder({
  output(frame) {
    // frame: AudioData,可 copyTo 到 Float32Array
    const buf = new Float32Array(frame.numberOfFrames);
    frame.copyTo(buf, { planeIndex: 0, format: 'f32-planar' });
    frame.close();                     // 必须显式关闭,否则泄漏
  },
  error(e) { console.error(e); },
});

const support = await AudioDecoder.isConfigSupported({
  codec: 'opus', sampleRate: 48000, numberOfChannels: 2, bitrate: 64000,
});
if (support.supported) {
  decoder.configure({
    codec: 'opus', sampleRate: 48000, numberOfChannels: 2, bitrate: 64000,
  });
}

关键点:

  • AudioData 必须 close():它持有底层缓冲,不关闭会迅速耗尽内存。
  • isConfigSupported 是异步的:不同浏览器的支持矩阵不同,必须运行时探测。
  • 编码用 AudioEncoder:可把麦克风采集的数据编码成 Opus 或 AAC,再通过 WebSocket 发送。

把编解码搬进 WASM(例如 ffmpeg.wasm 或 libopus.wasm)是另一种方案,适合需要精确控制编码参数或需要 WebCodecs 不支持的编解码器时,细节见 wasm-media-processing-codecs 。

9. 质量实测与评估方法

9.1 客观指标

  • PESQ:语音质量感知评估,输出 MOS-LQO(1~4.5)。适合窄带/宽带语音。
  • POLQA:PESQ 的继任者,支持超宽带。
  • ViSQOL:基于频谱相似度,适合音乐与通用音频。
  • PEAQ:ITU-R BS.1387,面向音乐质量。

这些工具都需要"参考信号 + 处理信号"配对,且对时间对齐敏感。

9.2 主观测试

MUSHRA(ITU-R BS.1534)是音频编解码评估的事实标准:给受试者一个参考信号与多个候选,要求按 0100 打分,其中必须包含一个 3.5 kHz 低通的"锚点"用于校准。至少 1520 名受试者才能得到统计显著的结果。

9.3 快速验证:null test 与频谱对比

# 用 Opus 编码再解码,与原信号做差
ffmpeg -i ref.wav -c:a libopus -b:a 96k tmp.opus
ffmpeg -i tmp.opus -c:a pcm_s24le decoded.wav
ffmpeg -i ref.wav -i decoded.wav -filter_complex \
  "[0:a][1:a]amix=inputs=2:weights=1 -1,volumedetect" -f null -

残差电平反映"丢掉了多少信息",但不能直接换算成主观质量——这正是需要 PESQ/MUSHRA 的原因。完整的音频质量测试体系见 audio-quality-testing。

权衡取舍

决策点选择 A选择 B建议
编解码器OpusAAC实时一律 Opus;点播考虑硬件解码用 AAC
帧长20 ms60 ms交互 20 ms,非交互 60 ms
码率模式CBRVBR实时 CBR,离线 VBR
低码率方案HE-AACOpus广播兼容用 HE-AAC,Web 用 Opus
抗丢包FECNACK两者同时开,比例由拥塞控制决定
立体声联合立体声双声道低码率用联合/参数立体声
音频质量96 kbps256 kbps96 kbps 已接近透明,更高边际收益极小

常见坑清单

  1. 低码率用 AAC-LC:48 kbps 以下 AAC-LC 明显劣于 HE-AAC 与 Opus,应换编码器而非降码率。
  2. 高码率用 HE-AAC:128 kbps 以上 SBR 的合成高频反成负担,应回退到 AAC-LC。
  3. 忽略算法延迟:只算网络延迟会低估端到端延迟 30~60 ms,交互场景不可接受。
  4. 实时场景用 VBR:码率突变导致发送队列积压与抖动缓冲水位波动。
  5. 忘记 AudioData.close():WebCodecs 中不关闭 AudioData 会迅速耗尽内存。
  6. 假设所有浏览器都支持:必须用 isConfigSupported 运行时探测,Safari 的支持矩阵与 Chrome 差异明显。
  7. 帧长与打包间隔混淆:minptime 是打包间隔,可包含多个帧,不等于帧长。
  8. 只开 NACK 不开 FEC:RTT 大于抖动缓冲深度时重传来不及,必须配合 FEC。
  9. 以为 PLC 能恢复数据:丢包隐藏只是合成替代信号,丢包率高于 10% 时主观质量必然下降。
  10. 用峰值判断质量:编解码前后的峰值差异不能反映主观质量,需 PESQ/MUSHRA 等感知指标。

小结

音频编解码的选型本质是码率、延迟、抗丢包、兼容性四者的取舍。Opus 在延迟与码率上全面领先且免专利,是实时场景的默认选择;AAC 在硬件解码与广播生态上占优,是点播与低码率流媒体的主力。帧长决定算法延迟,码率模式决定传输稳定性,FEC 与 PLC 决定弱网体验。

落地时的顺序建议:先确定延迟预算,再反推帧长与打包间隔;先确定带宽下限,再选择编解码器与码率模式;最后用 PESQ 或 MUSHRA 验证主观质量是否达标。

继续深入建议读 audio-streaming-latency 理解抖动缓冲与端到端延迟的完整拆解,读 webrtc-codec-congestion-control 了解码率如何随网络自适应,读 audio-quality-testing 掌握客观与主观质量评估的完整方法。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「音频工程」更多文章

  1. 音视频同步与时间码
  2. 音频硬件接口与驱动栈
  3. 响度标准化与交付规范