track元素必须嵌套在含controls属性的video或audio内才生效,src需同源或配CORS,VTT文件须UTF-8无BOM、Content-Type为text/vtt且首行为WEBVTT。

track元素必须配合video或audio使用才能生效
单独写<track></track>标签浏览器完全忽略,它只是个“字幕轨道描述符”,不渲染也不加载。必须嵌套在<video></video>或<audio></audio>内部,且父媒体元素需有controls属性(否则即使加载成功也无法手动切换)。
常见错误是把<track></track>写在里,或者忘了给<video></video>加controls——这时控制栏不出现字幕按钮,用户根本看不到轨道选项。
-
<video controls><source src="a.mp4"><track kind="subtitles" srclang="zh" label="中文" src="zh.vtt"></track></source></video>✅ -
<video>...<track></track></video>❌(无controls,字幕不可见) -
<track src="zh.vtt"></track>❌(孤立存在,不触发任何加载)
src指向的VTT文件必须符合WebVTT格式且同源或配CORS
浏览器只认.vtt后缀,且内容开头必须是WEBVTT纯文本声明(不能有BOM、空行或注释在第一行)。路径必须可访问:若视频在https://example.com/video.mp4,而字幕在https://cdn.example.com/zh.vtt,则CDN响应头必须含Access-Control-Allow-Origin: *或精确匹配源,否则控制台报Failed to load resource: net::ERR_FAILED,但不会提示是CORS问题。
VTT示例(注意空行和时间格式):
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
WEBVTT 00:00:01.000 --> 00:00:04.500 欢迎观看演示视频 00:00:05.200 --> 00:00:08.900 这是第二句字幕
kind、srclang、label三个属性缺一不可
kind="subtitles"明确用途(不是captions或descriptions),srclang="zh"让浏览器识别语言(影响自动匹配),label="中文"是用户在右键菜单或设置里看到的名称。漏掉srclang会导致多语言场景下无法通过video.textTracks[0].language读取;漏掉label则菜单显示为空白项或默认“subtitles”。
- 英文+中文双轨:
<track kind="subtitles" srclang="en" label="English" src="en.vtt"></track>和<track kind="subtitles" srclang="zh" label="中文" src="zh.vtt"></track> - 浏览器会根据系统语言自动启用匹配
srclang的轨道(如果default未设) - 设
default属性可强制默认启用(如<track kind="subtitles" srclang="zh" label="中文" src="zh.vtt" default></track>)
动态添加track需用JS调用addTextTrack方法
直接video.appendChild(trackEl)无效,必须走API:video.addTextTrack("subtitles", "中文", "zh")返回一个TextTrack对象,再手动设置track.mode = "showing"并绑定src(但此时src赋值不会触发加载,得用fetch读VTT内容后调用track.addCue()逐条注入)。
更实用的做法是:先用<track hidden></track>占位,JS中修改src再移除hidden,或直接替换整个<video></video>DOM节点重新解析。
注意:动态添加的track不会自动下载VTT,除非其mode变为"showing"或"hidden"("disabled"状态不加载)。
真正容易被忽略的是VTT文件编码和服务器MIME类型:必须UTF-8无BOM,且服务器要返回Content-Type: text/vtt。Nginx/Apache没配的话,Chrome可能静默失败,Firefox则直接拒绝解析。别只盯着HTML写法,后端响应头和文件本身才是卡点。


















