audio元素中track的default属性基本无效,必须通过javascript在loadedmetadata事件后手动设置mode="showing",且kind须为"subtitles"、srclang合法、vtt文件符合规范,移动端safari完全忽略。

audio元素里加track默认语言,和video一样但更易失效
音频(<audio></audio>)支持<track></track>,但行为比<video></video>更保守:多数浏览器根本不会在音频控件里显示字幕开关,default属性几乎形同虚设。真正能起作用的,只有 JavaScript 主动设 mode = "showing",且必须等 loadedmetadata 事件后操作。
为什么audio加了default还是没字幕
常见原因不是代码写错,而是浏览器根本不渲染——<audio></audio> 默认无字幕 UI,即使 textTracks 列表里有轨道、mode 是 "showing",也不显示任何文字。这不是 bug,是规范允许的行为。
-
kind必须是"subtitles"(不是"captions"或"descriptions") -
srclang要合法,比如zh、en,不能写Chinese或zh-CN(后者虽可解析,但匹配系统语言时不如zh稳定) -
<track></track>必须紧贴在<source></source>后面,不能被包裹、不能放错位置 - VTT 文件必须返回
Content-Type: text/vtt,状态码 200,首行是WEBVTT,且无 BOM - 移动端 Safari 对
<audio></audio>的<track></track>完全忽略 —— 连textTracks都不加载
audio字幕默认语言必须用JS动态设
靠 HTML 的 default 属性在 <audio></audio> 上基本无效。正确做法是监听 loadedmetadata,再按用户语言偏好匹配并启用:
audio.addEventListener('loadedmetadata', () => {
const lang = navigator.languages?.[0]?.split('-')[0] || 'zh';
const track = Array.from(audio.textTracks).find(t =>
t.kind === 'subtitles' && t.srclang?.startsWith(lang)
);
if (track && track.readyState === 2) {
track.mode = 'showing';
}
});
注意点:
-
textTracks是实时集合,必须等loadedmetadata触发后才能遍历 -
track.readyState === 2表示 VTT 已加载完成,此时设mode才可靠;值为 0(not loaded)或 1(loading)时设会静默失败 - 不要依赖
default属性来“兜底”,它在<audio></audio>中既不触发 UI,也不保证mode变为"showing" - 如果想让用户看到字幕,得自己实现一个浮动层或外挂字幕容器,监听
timeupdate并手动渲染当前 cue 文本
audio字幕实际可用性极低,优先考虑替代方案
除非你控制播放环境(如 Electron 桌面应用或 WebView 内嵌),否则别指望原生 <audio></audio> + <track></track> 能稳定显示字幕。更现实的做法:
- 把音频和字幕合成一个带字幕的视频(
<video></video>+ 黑色背景),绕过音频限制 - 用 Web Audio API + 自定义 DOM 字幕层,完全接管时间轴和文本渲染
- 服务端直接输出带内嵌字幕的 MP4(如使用 FFmpeg 的
-vf subtitles=xxx.vtt),浏览器无需解析 track
真正容易被忽略的点是:音频字幕不是“功能没做对”,而是“浏览器压根没打算让它对”——规范没要求音频必须显示字幕,所有尝试都属于 hack 范畴。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











