字幕不显示主因是track标签未被识别,须满足结构(video直接子元素、紧贴source后)、属性(kind/srclang/label缺一不可)、文件格式(.vtt首行WEBVTT、UTF-8无BOM、Content-Type:text/vtt)三重严格条件。

字幕不显示,大概率不是代码写错了,而是 track 标签没被浏览器识别——它对结构、属性、文件格式三者都极其苛刻,错一个环节就静默失败。
track 必须是 video 的直接子元素,且紧贴 source 之后
浏览器只认一种嵌套顺序:video → source(可多个)→ track(可多个)→ /video。任何偏移都会导致字幕菜单为空、控制栏无选项、控制台也不报错。
-
track不能放在source前面(哪怕只差一行) -
track不能写在video外部,比如套在div里,或紧跟在video标签后面 - 多个
track之间不能插注释、空行、span或其它标签(部分浏览器会中断解析) - 正确示例:
<video controls><br> <source src="movie.mp4" type="video/mp4"><br> <track kind="subtitles" src="zh.vtt" srclang="zh" label="中文(简体)" default><br> <track kind="subtitles" src="en.vtt" srclang="en" label="English"><br></video>
kind、srclang、label 三个属性缺一不可
这三个不是“建议填写”,而是浏览器识别轨道的硬性字段。缺任意一个,track 就被完全忽略。
-
kind="subtitles":必须是这个字符串,不能是"caption"、"captions"、"subtitle",也不能带空格或大小写偏差 -
srclang:必须是合法 BCP 47 语言码,如"zh"、"zh-Hans"、"en-US";"ch"、"chinese"、"cn"全部无效 -
label:用户在右键字幕菜单里看到的名字,为空时可能显示"(no label)",无法区分语种;建议含括号注明变体,如"中文(繁體)"
.vtt 文件必须过四关才真正可用
src 指向的 .vtt 文件,得同时满足以下四点,否则加载失败但无提示:
立即学习“前端免费学习笔记(深入)”;
- HTTP 状态码必须是
200(本地开发用file://协议时必挂,必须起本地服务) - 服务端必须返回
Content-Type: text/vtt(Nginx/Apache 需显式配置 MIME 类型) - 文件首行必须严格为
WEBVTT(全大写、顶格、无空格、无 BOM) - 编码必须是 UTF-8 无 BOM(VS Code 右下角选 “Save with Encoding” → UTF-8)
- 时间戳格式必须为
00:00:01.234 --> 00:00:04.567(毫秒三位、箭头前后各一个空格,少一位或多一位都解析失败)
default 属性只能设在一个 track 上,且不等于“自动启用”
default 表示页面加载时该轨道进入 mode = "showing",但有严格限制:
- 只能在一个
track上设置,设多个等同于没设 - 即使设了
default,如果用户手动关闭字幕,刷新后也不会恢复——浏览器不会持久化这个状态 - 想实现“刷新后仍保持上次选择”,必须用 JavaScript 读取
video.textTracks并手动设置mode - 注意:
mode只能是"disabled"、"hidden"或"showing",没有"auto"
最常被忽略的是服务端 MIME 类型和 VTT 文件首行格式——它们不出错、不报警,但字幕就是不出来。调试时先打开开发者工具的 Network 面板,确认 .vtt 请求返回的是 200 和 text/vtt,再下载那个 .vtt 文件用文本编辑器检查第一行和编码。这两步跳过,后面全白搭。



















