直接修改 的 src 属性无效,因浏览器仅在初始化时加载一次;动态切换字幕须预置多条 并通过 textTracks[i].mode 控制显隐,或弃用原生方案改用自定义 DOM 渲染。

不能用 HTML 标签直接替换字幕内容——<track></track> 是只读声明式容器,改 src 属性不会触发重载,也不会更新已渲染的字幕。
为什么直接改 <track src="old.vtt"></track> 没反应
浏览器只在 <video></video> 初始化时加载一次 src 指向的 WebVTT 文件;后续 JavaScript 修改 track.src 属于无效操作,textTracks 列表里的轨道对象本身不监听属性变更。
常见错误现象:document.querySelector("track").src = "new.vtt" 执行后字幕完全不变,控制台也无报错。
- 真正生效的前提是:所有语言的
<track></track>标签已在 HTML 中静态写好(即预加载) - 切换靠的是
track.mode控制显隐,不是换src - 若只有一条
<track></track>,必须先用DOMParser或服务端重生成 HTML 才能“换源”
用 video.textTracks 切换已有轨道(推荐)
这是唯一符合 HTML5 规范、无需刷新页面的动态切换方式,前提是多语言 <track></track> 已在 HTML 里声明完毕。
立即学习“前端免费学习笔记(深入)”;
示例结构:
<video id="myVideo"> <source src="movie.mp4"> <track kind="subtitles" src="zh.vtt" srclang="zh" label="中文" default> <track kind="subtitles" src="en.vtt" srclang="en" label="English"> </video>
切换逻辑:
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
-
video.textTracks[0].mode = "disabled"关闭当前激活轨道 -
video.textTracks[1].mode = "showing"开启目标轨道(索引需按顺序核对) - 不要依赖
srclang动态查索引——textTracks顺序与 HTML 中声明顺序严格一致
需要实时替换字幕文本?别碰 <track></track>,用自定义层
当字幕内容来自 API、需运行时拼接、或要支持富文本/样式微调时,<track></track> 天然不适用。此时应放弃原生方案,自己接管渲染。
核心步骤:
- 监听
video.addEventListener("timeupdate", ...)获取当前播放时间 - 查表匹配对应时间戳区间的字幕文本(WebVTT 解析可用
webvtt-parser库或手写简单解析) - 把文本塞进一个绝对定位的
<div id="subtitle">,并确保其 <code>font-size、line-height、text-align等样式继承自视频容器 - 注意防抖:避免每毫秒都触发 DOM 更新,建议节流到 50ms 以上
- VTT 文件头部必须是
WEBVTT(顶行、全大写、无空格) - 确认替换字符串不出现在时间码行或注释行(VTT 注释以
NOTE开头) - Windows 用户注意:用
PowerShell的(Get-Content).Replace()比sed更可靠,避免编码乱码
关键点:WebVTT 时间格式必须为 00:00:01.234 --> 00:00:03.456,毫秒位三位,少一位 Chrome 就静默失败。
批量修正本地 VTT 文件内容?用 sed 或 Python 脚本
如果字幕错误是静态的(比如所有 “妳” 都该为 “你”),且你有文件访问权限,最稳的方式是直接改 VTT 源文件——它本质是 UTF-8 文本,不涉及 HTML 解析风险。
安全前提:
Python 示例(安全替换正文文本,跳过时间码和注释):
import re
with open("zh.vtt", encoding="utf-8") as f:
lines = f.readlines()
new_lines = []
for line in lines:
if re.match(r"^\d{2}:\d{2}:\d{2}\.\d{3} --> \d{2}:\d{2}:\d{2}\.\d{3}$", line.strip()) or line.strip().startswith("NOTE"):
new_lines.append(line)
else:
new_lines.append(line.replace("妳", "你"))
with open("zh.vtt", "w", encoding="utf-8") as f:
f.writelines(new_lines)
真正容易被忽略的是:VTT 文件保存时必须用 UTF-8 无 BOM 编码,否则 Safari 会拒绝加载。


















