浏览器原生 video 标签不支持同时显示多个 track,同一 kind 下仅允许一个字幕轨道启用;需用 javascript 创建两个独立 div 层叠加渲染双语字幕,并通过 timeupdate 或 requestanimationframe 同步时间轴,严格对齐时间码,避免错位与性能问题。

video 标签本身不支持同时显示多个 track
浏览器原生 <video></video> 只会激活一个 <track kind="subtitles"></track>,即使你写了多个、都设为 default,最终也只渲染其中一个。这是规范行为,不是 bug —— HTML5 规范明确要求同一 kind 下最多一个 track 处于启用状态。
用 JavaScript 手动叠加字幕层是唯一可行方案
必须放弃依赖原生 track 渲染,改用两个独立的 <div> 层(比如上层中文、下层英文),监听 <code>timeupdate 事件,根据当前播放时间查找并显示对应文本。关键点:
- 每个字幕文件需解析成时间轴数组,例如
[{start: 1.2, end: 3.5, text: "你好"}, ...] - 两套字幕需严格对齐时间码,否则会出现错位或不同步
- 推荐用 WebVTT 解析库(如
vtt.js)处理 .vtt 文件,避免手写解析器出错 - 渲染时用
position: absolute+transform: translateY()分开定位,避免 DOM 重排影响性能
注意 track 的 srclang 和 label 不影响显示逻辑
即使你给两个 <track></track> 设置了不同 srclang="zh" 和 srclang="en",或者在 <track></track> 上加 label="中文" / label="English",这些属性只用于用户在浏览器字幕菜单里选择,无法触发双显。真正起作用的是 JavaScript 控制的 DOM 层。
常见误区:以为加上 default 就能默认启用两个 —— 实际上浏览器会忽略第二个 default,甚至可能报 warning:Multiple <track> elements with the default attribute are not supported</track>。
移动端和 Safari 的兼容性要额外验证
iOS Safari 对 timeupdate 事件触发频率较低(尤其后台播放时),可能导致字幕跳帧;部分安卓 WebView 对 WebVTT 解析不完整,建议 fallback 到纯 JSON 字幕格式。实操建议:
- 用
requestAnimationFrame替代纯timeupdate做更平滑的时间匹配 - 字幕 DOM 节点复用(而非频繁 create/remove),减少重绘压力
- 测试时务必关掉系统“缩减动画”开关,否则某些机型会抑制字幕更新
真正难的不是写两行字幕,而是让它们在各种设备上不卡、不错位、不漏帧 —— 时间轴精度、事件节流、DOM 更新策略,这三块最容易被忽略。











