track元素不支持分集功能,仅用于时间轴对齐文本轨道(如字幕、章节),无法切换视频文件或实现分集导航;分集需通过JavaScript动态切换video的src属性并重新挂载对应track。

track 元素本身不支持“分集”功能
track 是 HTML5 中用于添加视频/音频的**时间轴对齐文本轨道**(如字幕、章节、描述)的元素,它只负责在特定时间点显示文本内容,**不能跳转、不能切换不同视频文件、也不具备“分集”导航能力**。所谓“视频分集”,本质是多个独立视频资源的组织与切换,track 完全不参与这个过程。
常见误解是把 track kind="chapters" 当成分集菜单——它只能渲染一个章节标题列表(类似进度条上方的小标签),点击后仅能跳转到当前视频内的某个时间点,无法加载第2集、第3集等新视频。
实现分集的正确组合:video + 自定义按钮 + JavaScript 切换 src
真正可行的做法是:用一组按钮控制 <video></video> 的 src 属性,每次点击加载对应集数的视频文件;再配合 track kind="chapters" 为每一集单独提供章节信息(可选)。
关键实操点:
立即学习“前端免费学习笔记(深入)”;
- 每集视频应为独立文件(如
ep1.mp4、ep2.mp4),不要试图把多集塞进一个大文件里靠track拆分 - 按钮需绑定
onclick或事件监听器,修改video.src后调用video.load()和video.play()(后者可选) - 如果需要为每集配章节轨,
track标签必须**随src动态更新或重新挂载**——静态写死的track只对初始src生效 - 注意跨域限制:若视频资源在其他域名下,需确保服务端返回
Access-Control-Allow-Origin
示例片段:
<video id="player" controls>
<source src="ep1.mp4" type="video/mp4">
<track kind="chapters" src="ep1-chapters.vtt" default>
</video>
<button onclick="loadEpisode('ep1.mp4', 'ep1-chapters.vtt')">第1集</button>
<button onclick="loadEpisode('ep2.mp4', 'ep2-chapters.vtt')">第2集</button>
<script>
function loadEpisode(src, trackSrc) {
const v = document.getElementById('player');
v.src = src;
// 清除旧 track
v.querySelectorAll('track').forEach(t => t.remove());
// 插入新 track
const t = document.createElement('track');
t.kind = 'chapters';
t.src = trackSrc;
t.default = true;
v.appendChild(t);
v.load();
}
</script>
chapters.vtt 文件格式要严格,否则章节不显示
kind="chapters" 依赖 WebVTT 格式的章节文件,格式错误会导致整个章节轨被浏览器忽略——不是报错,而是静默失效。
必须满足的条件:
- 文件首行必须是
WEBVTT(全大写,无空格,无 BOM) - 每个章节块之间用空行分隔
- 时间戳格式为
HH:MM:SS.mmm --> HH:MM:SS.mmm,毫秒必须三位(如00:01:23.450,不能写成00:01:23.45) - 时间戳后必须紧跟章节标题文本,且不能有空行或注释行混入中间
正确示例(ep1-chapters.vtt):
WEBVTT 00:00:00.000 --> 00:02:15.000 片头 00:02:15.000 --> 00:23:40.000 第一幕 00:23:40.000 --> 00:45:10.000 第二幕
移动端和 Safari 对 chapters 支持有限
iOS Safari 和部分安卓 WebView **不渲染 kind="chapters" 的 UI**(即不会在进度条上方显示章节标记),即使 VTT 格式完全正确。用户只能看到普通进度条,无法点击跳章。
这意味着:如果你依赖章节轨做“分段导航”,在这些环境下实际等于失效。更稳妥的方式是——自己用 HTML + CSS 实现章节按钮栏,并用 video.currentTime 控制跳转,而不是指望浏览器原生章节 UI。
容易被忽略的一点:即使浏览器支持章节轨,它也**从不触发 JavaScript 事件**。你无法监听“用户点击了哪个章节”,所以所有交互逻辑(比如同步高亮、记录观看位置)都得绕开原生章节轨,改用自定义控件+时间监听来实现。



















