html5视频字幕需webvtt文件与track标签严格协同:首行必须顶格全大写webvtt、后跟空行、时间戳为hh:mm:ss.mmm→hh:mm:ss.mmm、utf-8无bom;track须为video直接子元素且在source后,kind、srclang、src、label四属性缺一不可。

track 标签不是“加个字幕就行”的装饰性语法,它直接决定视障、听障用户能否真正使用你的视频。没配对、配错或漏掉任一环节,轨道就根本不会出现在播放器菜单里——浏览器不报错,只是静默丢弃。
WebVTT 文件必须零容错:首行、编码、时间格式全卡死
浏览器对.vtt 文件的解析是硬校验,不是软提示:
- 首行必须是顶格、全大写、无空格、无 BOM 的 WEBVTT(写成 webvtt、WebVTT 或带空格/换行都会失败)
- 时间戳必须严格为 00:00:01.234 --> 00:00:04.567:小时/分钟/秒两位,毫秒三位,箭头前后各两个空格,多一个少一个都无效
- 编码必须是 UTF-8 无 BOM:Windows 记事本默认带 BOM,务必用 VS Code、Sublime 或 Notepad++ 选“UTF-8 without BOM”保存
- 中文、日文等非 ASCII 字符若显示为方块或问号,说明编码已污染;可用在线工具(如 vtt-validator.org)快速验证文件是否干净
track 必须嵌在 video 内且位置绝对固定
track 不是“写在 video 里就行”,而是有唯一合法位置:
- 必须是 video 的**直接子元素**
- 必须位于所有 source 标签**之后**、 **之前**
- 常见错误包括:track 写在 source 前面、套在 div 里、放在 video 外、或用 JS 动态插入——全部静默失效,控制台无任何提示
- 正确结构示例:
<video controls><source src="movie.mp4" type="video/mp4"><track kind="subtitles" src="zh.vtt" srclang="zh" label="中文" default><track kind="descriptions" src="desc.en.vtt" srclang="en" label="Audio Description"></track></track></source></video>
四个属性缺一不可,值必须合法
浏览器只认显式声明,不推断、不降级、不宽容: -kind:必须是 subtitles、captions、descriptions 等之一;subtitle(少 s)或空值会被当作 metadata 处理,字幕菜单里完全不出现
- srclang:必须是标准 BCP 47 语言标签,如 zh-Hans、en-US、ar;chinese、cn 无效
- label:不能为空;否则菜单里显示“(no label)”或“字幕”,用户无法区分中/英/日
- src:路径需可访问;本地开发时 file:// 协议下所有 .vtt 加载均失败,必须起本地服务(如 python3 -m http.server)
服务端配置和跨域常被忽略但致命
track 的 src 是独立 HTTP 请求,受完整 CORS 和 MIME 限制:
- 服务器必须返回 Content-Type: text/vtt;Nginx/Apache 需显式配置 MIME 类型,否则 Safari 可能拒绝解析
- 若字幕与视频不同源(如视频在 https://site.com,字幕在 https://cdn.site.com),服务端响应头必须包含 Access-Control-Allow-Origin: * 或具体域名
- 路径区分大小写:zh.vtt 和 ZH.VTT 在 Linux 服务器上是两个资源,404 时控制台只显示“Failed to load resource”,不会提示大小写问题
真正难的不是写几行 HTML,而是从字幕文件生成、编码保存、路径书写、服务端响应到浏览器加载全流程闭环验证。任意一环出错,用户看到的都是“没有字幕选项”——而不是“字幕加载失败”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











