1. 课程导入
音频延迟,说白了就是「声音从发出到听见之间的时间差」。
你对着麦克风说一句话,耳机里听到自己的声音慢了半拍——这就是延迟。我刚开始做 Web Audio 时,觉得这玩意儿不就是个时间差嘛,能有多复杂?直到第一次做实时合唱应用,用户反馈「根本没法唱」,我才意识到延迟是音频应用里最隐蔽的杀手。
1.1 什么是音频延迟
音频延迟,专业点说,是音频信号从源头(麦克风、文件、合成器)经过采集、处理、传输、播放这一整条链路,最终到达人耳所消耗的时间。
在浏览器里,这条链路长这样:
- 采集端:麦克风拾音 → 模数转换 → 进入 AudioContext
- 处理端:AudioNode 链式处理(滤波、混音、特效)
- 播放端:数模转换 → 扬声器发声 → 声波传到耳膜
每个环节都会引入延迟。我见过不少新手以为「只要代码跑得快就没延迟」,其实硬件和驱动层面的延迟往往比 JS 执行时间大得多。
核心认知:延迟不是 Bug,是物理定律。我们的目标不是消灭延迟,而是把它控制在人耳无法察觉的范围内。
1.2 延迟的测量单位
测量延迟,最常用的单位有两个:毫秒(ms)和采样点(samples)。
毫秒(ms)
毫秒是给人看的。人耳对延迟的感知大致分几个档:
| 延迟范围 | 用户体验 |
|---|---|
| 0 – 10 ms | 几乎无感,像面对面说话 |
| 10 – 20 ms | 专业监听可接受,普通用户基本察觉不到 |
| 20 – 50 ms | 有明显「回音感」,实时演奏/通话开始受影响 |
| 50 – 100 ms | 延迟明显,对话需要等待,节奏感被破坏 |
| > 100 ms | 完全无法实时交互,像对讲机 |
我个人习惯把 20 ms 当作红线。超过这个值,用户就会开始皱眉。
采样点(samples)
采样点是给机器看的。数字音频系统以「块」为单位处理数据,这个块的大小就叫 buffer size,单位就是采样点。
举个例子:采样率 44100 Hz,buffer size 128 samples,那么一个 buffer 的时长就是:
128 / 44100 ≈ 0.0029 秒 = 2.9 ms
为什么用采样点?因为音频引擎内部是按采样点做循环的。你写一段 ScriptProcessorNode 或 AudioWorklet 的代码,每次回调处理的就是固定数量的采样点。
换算公式:延迟(ms)= buffer size(samples)÷ 采样率(Hz)× 1000
记住这个公式,调试时能省不少时间。
1.3 延迟对用户体验的影响
延迟不是「有或没有」的问题,而是「多少算多」的问题。不同场景的容忍度天差地别。
实时通信场景
视频通话、在线K歌、远程演奏——这些场景对延迟最敏感。我记得有一次帮一个在线音乐教育平台做调试,老师弹钢琴,学生听到的伴奏慢了 40 ms。老师反馈「学生总是抢拍」,其实不是学生的问题,是延迟在捣鬼。
- 10 ms 以内:专业级体验,适合实时合奏
- 10 – 30 ms:普通通话可接受,但音乐演奏会难受
- 30 – 50 ms:对话开始有「重叠感」,需要刻意停顿
- 超过 50 ms:基本没法正常交流
录音监听场景
歌手录歌时,耳机里听到自己的声音如果延迟超过 10 ms,就会不自觉地拖拍或抢拍。这叫「延迟干扰效应」。我曾经踩过这个坑——给一个录音棚做 Web 版监听工具,没处理好延迟,歌手录了三遍都找不到节奏,最后换回本地软件了。
游戏与交互场景
游戏音效、UI 反馈音、虚拟现实——这些场景里,延迟会直接破坏沉浸感。你按下一个按钮,0.5 秒后才听到「咔嗒」声,用户会觉得这个应用「很笨重」。
注意:视觉和听觉的延迟叠加效应更可怕。如果画面延迟 30 ms,声音延迟 30 ms,用户感知到的不是 60 ms,而是「音画不同步」的撕裂感。这在视频播放和游戏中尤其致命。
1.4 延迟的构成:一张图看懂
为了让你更直观地理解延迟从哪里来,我画了一张链路图:
1.5 一个简单的延迟测试方法
说了这么多理论,不如动手测一下。在浏览器里,我们可以用 AudioContext 的 baseLatency 和 outputLatency 属性获取系统延迟:
const ctx = new AudioContext();
console.log('基础延迟:', ctx.baseLatency, '秒');
console.log('输出延迟:', ctx.outputLatency, '秒');
console.log('总延迟:', ctx.baseLatency + ctx.outputLatency, '秒');
不过要注意,这两个属性不是所有浏览器都支持。Chrome 支持得比较好,Safari 嘛……嗯,你懂的。
实测技巧:用 performance.now() 在 AudioWorklet 的 process 方法里打时间戳,可以精确测量处理延迟。我一般会在开发环境里加一个「延迟仪表盘」,实时显示当前链路的延迟值,调试起来一目了然。
1.6 小结
音频延迟不是什么玄学,它就是信号从 A 到 B 花的时间。测量单位记住两个:毫秒(给人看)和采样点(给机器看)。用户体验上,20 ms 是分水岭,超过这个值就要警惕了。
这一章是基础,但基础不牢,后面所有优化技巧都是空中楼阁。你想想看,如果你连延迟从哪里来、怎么测都不知道,又怎么能把它降下去呢?