字幕不显示90%是kind写错、src路径失效或track位置错误;track必须嵌套在video内且紧接source后,kind只能为subtitles/captions/descriptions,srclang须用标准BCP 47码,src指向可访问的WebVTT文件并返回text/vtt MIME类型。

字幕不显示,90% 是 kind 写错、src 路径失效或 track 放错位置——不是浏览器问题,是 HTML 结构或属性值没对。
track 必须嵌套在 video/audio 内部,且顺序不能错
浏览器只认直接子元素,且必须在所有 <source> 之后、</video> 或 </audio> 之前。写在外部、包裹在 <div> 里、插在 <source> 前面,都会被静默忽略——控制台不报错,但 video.textTracks.length 永远是 0。
-
<video><source src="a.mp4"><track kind="subtitles" src="zh.vtt"></video>✅ 正确 -
<video><track><source></video>❌track在source前,无效 -
<video></video><track>❌ 在video外,完全不注册 -
<video><div><track></div></video>❌ 不是直接子元素,被跳过
kind 属性只能是 subtitles/captions/descriptions,拼写一个字母都不能错
kind 不是“建议值”,而是浏览器识别轨道类型的唯一开关。写错或留空,整条 track 就不会进 textTracks 列表,JS 查不到,播放器菜单也不出现。
- 要显示对话翻译:必须用
kind="subtitles"(注意复数 s),kind="subtitle"或kind="subtitiles"全无效 - 要服务听障用户(含 [门铃响]、[笑声] 等声音提示):用
kind="captions",播放器常标为 “CC” - 要提供画面描述供屏幕阅读器读出:用
kind="descriptions",不显示在视频上 -
kind="chapters"或kind="metadata"不能当字幕用,它们不触发文字渲染 - iOS Safari 对
kind最严格:哪怕kind="subtitles "(末尾多空格)也会拒绝加载
src 必须指向可访问的 .vtt 文件,且服务端返回 text/vtt MIME 类型
src 看似只是路径,但背后有三道关卡:文件可访问、格式合法、MIME 正确。任一失败,track.readyState 会卡在 1(LOADING)或变成 3(ERROR),但控制台通常不报错。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
- 路径必须能被浏览器直接请求到,比如
src="sub/zh.vtt"—— 如果 404,track仍注册进列表,但readyState === 0或3 - VTT 文件首行必须是全大写
WEBVTT,不能带 BOM,时间戳毫秒必须三位(00:01:23.456),否则 Chrome 可能加载但不渲染 - 服务器必须返回
Content-Type: text/vtt;用 Nginx/Apache 配置时别漏掉,本地 file:// 协议下多数浏览器直接禁用track加载 - 跨域时,服务端需带
Access-Control-Allow-Origin,否则readyState停在1,JS 无法读取内容
srclang 和 label 缺一不可,尤其 srclang 是 JS 定位轨道的唯一依据
srclang 不是“装饰”,它是浏览器匹配系统语言、JS 脚本切换轨道、播放器菜单分组的核心字段。写错就等于轨道“隐形”。
-
srclang必须是标准 BCP 47 码:"zh"、"en-US"、"ja"合法;"ch"、"zh_CN"、"chinese"全无效 -
label是用户在播放器字幕菜单里看到的名字,缺失时菜单只显示 “字幕” 或 “CC”,无法区分中/英/日 - 多个同
kind的轨道(如两个kind="subtitles"),必须靠srclang + label组合唯一识别,否则video.textTracks[0].srclang可能返回空字符串 - Safari 中,即使
srclang正确,track.mode默认仍是"disabled",必须等readyState === 2后手动设为"showing"
真正容易被忽略的是:移动端 Safari 完全不响应 default,也不自动显示字幕按钮;track 加载完成 ≠ 可见,readyState === 2 才是安全操作的前提。别只在桌面 Chrome 测试,真机连 Safari DevTools 看 textTracks 列表才是准的。


















