浏览器默认不自动启用字幕,需用户手动开启; 仅声明资源,default 表示默认选中而非自动显示;kind="subtitles"、合法 srclang、http 服务、正确 dom 位置及 .vtt mime 类型缺一不可。

为什么加了 <track></track> 字幕就是不显示
浏览器默认不自动启用任何字幕轨道,<track></track> 只是声明资源,不是“打开就见字幕”的开关。用户必须手动点击播放器的「字幕」按钮并选择一条——哪怕你写了 default 属性,也只是表示“加载时默认选中”,仍需用户主动开启。
-
kind必须是"subtitles"(不是"captions"或"metadata"),否则不会出现在字幕菜单里 -
srclang要用合法 BCP 47 码,比如"zh"、"en-US",空值或"chinese"这类非标准写法会被忽略 - VTT 文件必须通过 HTTP 服务访问(
file://协议下因 CORS 限制会静默失败) -
<track></track>必须作为<video></video>的直接子元素,且放在所有<source></source>之后、其他内容之前 - DevTools Network 面板里确认
.vtt返回 200;Console 查看有没有Failed to load resource提示
video.textTracks 怎么控制字幕显隐
想绕过 UI 手动控制字幕(比如根据用户偏好自动开启),得用 JS 操作 textTracks 列表,但要注意:浏览器对 mode 的设置有严格限制,不能靠 track.mode = 'showing' 就强制显示——前提是该轨道已被用户“启用”(即在播放器菜单里勾选过)。
- 遍历
video.textTracks找到目标轨道:track.kind === 'subtitles' && track.language === 'zh' - 只有当
track.mode !== 'disabled'时,才能设为'showing';否则设了也无效 - 真正可靠的自动化方式是监听
textTracks.onchange,再结合track.mode状态做响应,而不是一上来就硬设 - 如果页面加载后立即调用
track.mode = 'showing'失败,大概率是因为轨道还没加载完成,应等track.readyState === 2(loaded)后再操作
音频描述(descriptions)轨道为什么几乎没人用
因为主流浏览器根本不支持自动播放独立的 kind="descriptions" 音轨——<track kind="descriptions"></track> 本质只是个元数据提示,供屏幕阅读器识别存在描述资源,但不会触发语音播放。
- 最可靠方案是提供一个已把描述语音混入主音轨的备用视频文件,比如
movie-ad.mp4,并在页面放显眼链接:@#@#@#@#@#@#@#@#@#@0 - 若视频本身封装了多音轨(如 MP4 含 description audio track),可用
video.audioTracks检索,找audioTrack.label或audioTrack.id包含"description"的那条,再调用audioTrack.enabled = true - 注意:这种切换依赖容器格式支持,HLS/DASH 流更稳妥;纯 MP4 需用 FFmpeg 打包时明确标记音轨类型(
-disposition:0 description) - WebVTT 文件即使配了
kind="descriptions",也只用于同步控制或辅助设备读取时间戳,不等于能播声音
字幕与音轨共存时容易踩的坑
当同时用 <track></track> 字幕和 audioTracks 多音轨时,时间轴错位、状态不同步、键盘焦点丢失等问题会突然冒出来,尤其在用户频繁切换时。
- 字幕时间戳必须和主音轨对齐;如果用了带音频描述的备用视频,其字幕文件的时间轴要重新校准,不能直接复用原版 VTT
- 切换音轨后,
video.textTracks不会自动重载或刷新,已启用的字幕可能继续显示旧时间轴——需要手动track.mode = 'hidden'再'showing' - 播放控件的键盘可访问性(Tab 进入、Space 切换)在自定义播放器里极易被破坏;原生
controls属性虽简陋但最稳,自行重写务必测试 NVDA + Chrome 和 VoiceOver + Safari - 服务器必须返回正确的 MIME 类型:
.vtt → text/vtt,.mp4 → video/mp4,否则某些浏览器(尤其是 Safari)会拒绝加载轨道
真正的难点不在写几行 <track></track>,而在于理解浏览器对轨道的“被动管理”逻辑——它不替你做决定,只提供接口;所有看似自动的行为,背后都需要用户动作或 JS 显式干预。漏掉任意一环,可访问性就断在最后一厘米。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











