字幕不显示的根本原因是浏览器默认不启用轨道且需用户手动开启,同时要求kind为"subtitles"、srclang有效、vtt文件合规、路径正确且通过http服务访问。

HTML 的 <track></track> 标签本身不显示字幕——它只是声明轨道资源,真正控制显示的是 <video></video> 或 <audio></audio> 元素的播放器行为和用户设置。
为什么加了 <track></track> 却没看到字幕
这是最常遇到的问题:标签写了、属性填了、文件也放对路径了,但字幕就是不出现。
- 浏览器默认不自动启用任何轨道;必须由用户手动在播放器控件里点开「字幕」菜单并选择一条启用
-
kind值必须是"subtitles"(不是"caption"或"metadata"),否则不会出现在字幕菜单中 -
srclang必须是有效的 BCP 47 语言码(如"zh"、"en"),且不能为空;某些浏览器会因语言码不规范而跳过该轨道 - VTT 文件需满足 CORS 要求:本地双击打开 HTML 时,
file://协议下浏览器会拒绝加载外部.vtt,必须走 HTTP 服务(如python3 -m http.server)
<track></track> 必须放在 <video></video> 或 <audio></audio> 内部,且位置有讲究
它不是独立渲染元素,也不能放在媒体标签外面——放错位置等于无效。
- 必须作为
<video></video>或<audio></audio>的直接子元素,且要放在所有<source></source>之后、<div> 等其他内容之前 <li>多个 <code><track></track>可共存,但只有被用户选中的那条才会激活;浏览器不会合并或级联它们 - 如果用了
default属性,仅表示“页面加载时默认选中”,仍需用户开启字幕开关才能看到;default对kind="chapters"无效
正确示例:
<video controls><source src="movie.mp4" type="video/mp4"><track kind="subtitles" label="中文" srclang="zh" src="zh.vtt" default><track kind="subtitles" label="English" srclang="en" src="en.vtt"></track></track></source></video>
VTT 文件格式稍有出错,整个轨道就静默失效
浏览器对 WebVTT 解析非常严格,一个空格、时间格式错位、BOM 头都可能导致轨道加载失败(且不报错)。
- 文件必须以
WEBVTT开头,后面紧跟换行;不能有 UTF-8 BOM,也不能是 Windows 换行符\r\n(推荐用\n) - 时间戳格式必须为
HH:MM:SS.mmm,毫秒必须三位,如00:01:23.456,写成00:01:23.45或00:01:23.4567都会失败 - 文本行不能以空格开头,也不能包含 HTML 标签(即使转义也不行),只支持极简的
<b></b>、<i></i>、<u></u> - 调试建议:用浏览器 DevTools 的 Network 面板确认
.vtt返回状态码是 200,再看 Console 是否有Failed to load resource类提示
JavaScript 动态控制字幕需要绕过 UI 限制
想用 JS 默认打开字幕、或根据用户偏好自动切换?浏览器原生 API 支持有限,得靠变通。
-
video.textTracks是只读类数组,其中每个TextTrack的mode属性可设为"disabled"、"hidden"或"showing";设为"showing"才真显示 - 但首次访问
textTracks时,轨道可能还未加载完成,需监听load事件或轮询readyState === 2 - 注意:
mode = "showing"不等于用户在控件里点了字幕——它绕过了 UI,部分全屏模式下可能被重置 - 没有跨浏览器方法能“模拟点击字幕菜单”,所以依赖 UI 的场景(如无障碍需求)仍需引导用户手动操作
最容易被忽略的一点:字幕是否显示,最终取决于三个独立开关同时打开——<track></track> 的 kind 和 srclang 合法、VTT 文件内容零错误、用户在播放器里主动启用。少一个,就白配。











