原生 track 标签仅支持 WebVTT 字幕与本地音视频自动同步;流媒体、AudioContext、LRC/SRT 等需手动解析时间轴并注入 VTTCue 或 DOM 渲染。

track 标签本身不负责与音频同步——它只声明轨道,时间轴对齐靠浏览器自动解析 WebVTT 文件里的 00:01.234 --> 00:03.567 时间戳。但前提是:你用的是普通 audio 或 video 元素加载本地文件(MP3/MP4/WebM),且字幕是外挂的 .vtt 文件。
一旦涉及流媒体(HLS/DASH)、动态音频注入、或非标准字幕格式(如 .lrc、.srt),原生 track 就失效了。下面分场景说清楚怎么做、为什么、以及最容易卡住的地方。
外挂 WebVTT 字幕 + audio 元素能直接同步吗?
能,但有硬性前提:
-
audio必须已加载完成(onloadedmetadata触发后),再确保track在audio开始标签内、且default属性已设(否则不会自动启用) -
src指向的.vtt文件必须返回Content-Type: text/vtt,否则 Chrome/Firefox 会静默忽略 - WebVTT 文件首行必须是
WEBVTT(大小写敏感),空行后才能写 cue;任何 BOM、UTF-8 编码错误都会导致整个轨道加载失败 - 如果音频是通过
MediaSource动态拼接的(比如录音后转 Blob URL),track无法绑定,必须用addTextTrack()手动注入
想让字幕跟着 JS 控制的 AudioContext 音频走?
不行。AudioContext 是纯音频处理 API,不暴露时间轴给 textTracks,也没有 currentTime 属性。你得自己做时间映射:
- 记录每次
audioContext.currentTime启动播放的时刻,结合音频时长推算当前播放点 - 用
requestAnimationFrame或setTimeout轮询比对,手动更新 DOM 中的字幕文本(例如) - 别依赖
audio元素的timeupdate事件——它在AudioContext场景下根本不会触发 - 若需精确到毫秒级(如歌词高亮),建议把时间轴预计算成数组,用二分查找匹配当前播放位置,避免逐条遍历
用 .lrc 或 .srt 怎么喂给 audio?
浏览器原生不支持。必须转换+手动注入:
-
.lrc需正则提取[mm:ss.xx]并转为秒数,再生成合法 WebVTT 内容(含WEBVTT头和 cue 格式) -
.srt要修正序号、时间格式(00:01:23,456 --> 00:01:25,789→00:01:23.456 --> 00:01:25.789),并替换换行符为\n - 转换后不能直接设
track.src,得用audio.addTextTrack('subtitles', 'label', 'zh')创建轨道,再用track.mode = 'hidden'+track.cues手动添加VTTCue对象 - 注意:
VTTCue构造函数第三个参数是字符串,不是 HTML —— 即使含也会被转义,要用cue.text = 'xxx'并确保track.mode = 'showing'才渲染
关键点就一个:原生同步只发生在「浏览器控制解码 + WebVTT 时间戳严格匹配」这个闭环里。任何跳出这个闭环的操作(流媒体、自定义音频引擎、非 VTT 字幕),都得自己接管时间轴和渲染逻辑——textTracks 只是容器,不是调度器。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











