<track>标签必须作为<video>或<audio>的直接子元素,设置kind和src属性,使用符合WebVTT语法(含WEBVTT声明、正确时间戳)的UTF-8无BOM文件,并通过textTracks[i].mode控制显隐,注意移动端兼容性。

track 标签必须放在 video/audio 内部且紧邻 source
HTML 字幕不是“加个属性”就能生效,<track> 是独立标签,但必须作为 <video> 或 <audio> 的子元素,且不能包在 <source> 外面——常见错误是把它丢到 <video> 外面,或放在 <source> 之后但没闭合 video 标签。
-
<track>必须有kind="subtitles"(或其他合法值如"captions"、"descriptions")和src属性,否则浏览器直接忽略 -
srclang推荐写全(如"zh"或"en"),否则多语言切换时可能无法识别默认轨 - 如果用了
default属性,只允许一个<track>带它;多个会导致全部失效
字幕文件得是 WebVTT 格式,不是 SRT 直接改后缀就行
浏览器只原生支持 .vtt(WebVTT),哪怕内容和 SRT 一样,也必须符合 WebVTT 语法规范:开头必须有 WEBVTT 声明行,时间戳用 00:00:01.234 --> 00:00:04.567 格式,不能用 SRT 的序号行和空行分隔。
- SRT 转 VTT 不是改后缀,推荐用工具如
vtt-tools或在线转换器,手动改容易漏掉WEBVTT行或格式错位 - VTT 文件里不能有 UTF-8 BOM,否则 Chrome 可能解析失败,报错类似
Failed to load resource: net::ERR_INVALID_RESPONSE - 路径必须可跨域访问:如果 video 在 HTTPS 页面,
src指向的 VTT 也必须 HTTPS,否则被拦截且无明显提示
JavaScript 控制字幕开关得操作 textTracks 列表
DOM 上没有 video.subtitleEnabled 这种属性,启用/禁用靠遍历 video.textTracks 并设 mode:
const track = video.textTracks[0]; track.mode = 'showing'; // 或 'disabled'、'hidden'
-
textTracks是实时列表,动态添加<track>后会自动更新,但需等load事件后才可用 -
mode = 'showing'才真显示;'hidden'仍加载但不渲染;'disabled'完全不加载字幕数据 - 监听字幕变化要用
textTracks.onchange,不是onload或ontimeupdate
移动端 Safari 和旧版 Android 浏览器对 track 支持很有限
iOS Safari 默认隐藏字幕控件,且不响应 default 属性;部分 Android WebView(尤其 7.0 以下)根本不触发 textTracks 列表。
立即学习“前端免费学习笔记(深入)”;
- 别依赖原生控制条里的字幕按钮,建议自己做 UI 开关并用 JS 控制
mode - Android 低版本需 fallback:检测
video.textTracks.length === 0后,用 canvas 或 div 模拟字幕层 - 测试时务必真机验证,模拟器常误报支持
WebVTT 解析和 track 渲染是浏览器原生行为,一旦格式或位置出错,基本没中间态调试手段——错就是不显示,连 warning 都不一定抛。最稳的方式是先确保单个 VTT 文件能独立打开验证,再嵌入 HTML。











