HTML audio 的 loop 属性存在毫秒级停顿,无法真正无缝;Web Audio API 的 source.loop = true 才能实现无缝循环,但 MP3 格式因 ID3 帧和解码延迟仍存障碍,推荐使用 WAV 或 OGG 格式。

loop属性本身不支持无缝循环
loop 属性只是让浏览器在音频末尾自动跳回开头重放,中间存在毫秒级停顿(通常 50–200ms),尤其在 MP3 或 AAC 格式上明显可闻“咔哒”声。这不是 bug,而是规范行为——loop 不承诺时间连续性,也不触发解码器重置或缓冲区衔接。
真正无缝需靠 JavaScript + Web Audio API
用 AudioContext 手动控制播放时机,在音频结束前几毫秒启动下一段,避开解码/调度延迟。关键点:
-
AudioBufferSourceNode可精确控制开始时间(单位:秒,支持小数) - 必须提前
decodeAudioData加载完整音频,不能直接用src - 监听
onended事件不够准,要用scheduledStartTime + buffer.duration预判结束时刻 - 推荐用
start(when)而非start(),把下次播放时间算死
示例片段:
const context = new (window.AudioContext || window.webkitAudioContext)();
fetch('track.mp3').then(r => r.arrayBuffer())
.then(buf => context.decodeAudioData(buf))
.then(buffer => {
const source = context.createBufferSource();
source.buffer = buffer;
source.loop = true; // 这里 loop 是 Web Audio 的原生无缝 loop
source.connect(context.destination);
source.start(); // 自动无缝,无需手动调度
});注意:Web Audio 的 source.loop = true 才是真正无缝的,和 HTML <audio loop></audio> 完全不同机制。
MP3 格式是无缝循环的最大障碍
MP3 文件自带 ID3 帧、padding 和解码器延迟,即使 Web Audio 也难完全消除间隙。实际方案:
- 优先用
.wav或.ogg(带合适 header 的 Vorbis)——它们无额外帧开销 - 若必须用 MP3,用工具(如
ffmpeg)裁剪掉首尾静音,并确保采样率对齐:ffmpeg -i in.mp3 -c:a libmp3lame -q:a 0 -ar 44100 -ac 2 out.mp3
- 某些浏览器(如 Safari)对 MP3 loop 更不友好,实测 gap 比 Chrome 大 2–3 倍
audio 元素 fallback 方案只能妥协
如果坚持用 <audio></audio> 标签(比如需要原生控件、SEO 或简单场景),无缝不可行,只能降低感知:
立即学习“前端免费学习笔记(深入)”;
- 在音频开头加 100–200ms 淡入,结尾加等长淡出,掩盖切换点
- 用
preload="auto"+autoplay减少首次 loop 延迟 - 监听
ended事件后立即currentTime = 0并play(),但仍有可闻间隙
真正要求零感知的背景音乐、游戏音效、节拍器等场景,<audio></audio> 标签不是合适选择。



















