kind="subtitles"仅翻译对话供听懂语音者使用,kind="captions"含音效描述专为听障用户设计;二者语义不同,浏览器ui处理方式也不同,如chrome/edge标为“cc”,safari则不显示captions菜单项。

kind="subtitles" 和 kind="captions" 的区别在哪
浏览器把这两类字幕当不同用途处理,不是命名习惯问题,而是语义和 UI 行为差异。
kind="subtitles" 是给“能听见但听不懂语言”的人用的,只翻译对话,不描述音效;kind="captions" 是给听障用户设计的,必须包含说话人、环境音、音乐提示等(如 [电话铃响]、(轻快的钢琴声))。
播放器原生菜单里,Chrome 和 Edge 会把 captions 单独标为 “CC”(Closed Captions),而 subtitles 就叫“字幕”或按 label 显示;Safari 则完全不显示 captions 菜单项——它只暴露 subtitles 类型到 UI。
srclang 对两者都关键:JS 用 track.srclang === "zh" 查轨道,写成 "zh-CN" 或 "Chinese" 就匹配不上。
不要混用:同一视频里,en.vtt 若含音效说明,就该设 kind="captions";若只是对白翻译,就用 kind="subtitles"。
kind="descriptions" 不是音轨,别往 audio 标签里塞
kind="descriptions" 指向的是 WebVTT 文件里的**文字描述**,不是音频流,更不能替代多音轨切换。
它专为视障用户服务,内容是“画面发生了什么”,例如:00:01:22.000 --> 00:01:25.000
主角推开木门,门外阳光刺眼,一只黑猫蹲在台阶上。
浏览器不会把它渲染成字幕,也不会在音轨菜单里出现;屏幕阅读器读到它,才朗读这段描述。
常见错误:把 kind="descriptions" 放在 <audio></audio> 标签里——HTML 规范不支持 audio 元素加载描述轨道,该 track 会被静默忽略。
必须配 srclang(如 srclang="zh")和 label(如 label="中文描述"),否则 Safari 可能不加载。
kind="chapters" 渲染失败?先看浏览器和 VTT 格式
kind="chapters" 的目标是让浏览器在进度条下画章节标记,但目前只有 Safari(macOS/iOS)和 Edge(Chromium 90+)支持 UI 渲染,Chrome 和 Firefox 完全不显示。
VTT 文件必须严格满足三点:首行是 WEBVTT(后跟空行),时间戳递增且不重叠,每段格式为 HH:MM:SS.mmm --> HH:MM:SS.mmm 后换行再写标题(不能有空行、注释或额外字符)。
服务器必须返回 Content-Type: text/vtt;Nginx 需加 add_header Content-Type text/vtt;,Apache 要配置 AddType text/vtt .vtt。
srclang 对章节轨道无语义作用,但 Safari 有时因缺失而跳过加载,建议填个合法值如 srclang="zh";default 属性无效,章节轨道不支持默认启用。
kind="metadata" 是唯一能被 JS 读取但不渲染的轨道
kind="metadata" 不触发任何 UI,也不依赖 WebVTT 格式——它可以指向任意文本资源,只要响应头是 text/plain 或 application/json(注意:浏览器仍要求同源或 CORS)。
它的用途是让脚本读取结构化数据,比如章节元信息、广告位时间点、互动热点坐标。
track.mode 必须设为 "hidden" 或 "disabled" 才能触发 onload;设成 "showing" 会报错,因为没渲染目标。
VTT 文件里可以写 JSON 片段,但需确保 UTF-8 编码且无 BOM;更稳妥的做法是用纯文本每行一个键值对,JS 用 track.track.kind === "metadata" 过滤后解析。
别指望它兼容移动端:iOS Safari 加载 metadata 轨道时,track.readyState 常卡在 0,得监听 load 事件而非轮询状态。
真正容易被忽略的,是 kind 值必须字面量匹配、大小写敏感、不可拼错——"subtitle"、"subtitles "(尾部空格)、"Subtitles"(大写 S)全都会被浏览器当作非法值静默丢弃,连 video.textTracks 列表里都不会出现。
kind="descriptions" 指向的是 WebVTT 文件里的**文字描述**,不是音频流,更不能替代多音轨切换。
它专为视障用户服务,内容是“画面发生了什么”,例如:00:01:22.000 --> 00:01:25.000主角推开木门,门外阳光刺眼,一只黑猫蹲在台阶上。 浏览器不会把它渲染成字幕,也不会在音轨菜单里出现;屏幕阅读器读到它,才朗读这段描述。 常见错误:把
kind="descriptions" 放在 <audio></audio> 标签里——HTML 规范不支持 audio 元素加载描述轨道,该 track 会被静默忽略。
必须配 srclang(如 srclang="zh")和 label(如 label="中文描述"),否则 Safari 可能不加载。
kind="chapters" 渲染失败?先看浏览器和 VTT 格式
kind="chapters" 的目标是让浏览器在进度条下画章节标记,但目前只有 Safari(macOS/iOS)和 Edge(Chromium 90+)支持 UI 渲染,Chrome 和 Firefox 完全不显示。
VTT 文件必须严格满足三点:首行是 WEBVTT(后跟空行),时间戳递增且不重叠,每段格式为 HH:MM:SS.mmm --> HH:MM:SS.mmm 后换行再写标题(不能有空行、注释或额外字符)。
服务器必须返回 Content-Type: text/vtt;Nginx 需加 add_header Content-Type text/vtt;,Apache 要配置 AddType text/vtt .vtt。
srclang 对章节轨道无语义作用,但 Safari 有时因缺失而跳过加载,建议填个合法值如 srclang="zh";default 属性无效,章节轨道不支持默认启用。
kind="metadata" 是唯一能被 JS 读取但不渲染的轨道
kind="metadata" 不触发任何 UI,也不依赖 WebVTT 格式——它可以指向任意文本资源,只要响应头是 text/plain 或 application/json(注意:浏览器仍要求同源或 CORS)。
它的用途是让脚本读取结构化数据,比如章节元信息、广告位时间点、互动热点坐标。
track.mode 必须设为 "hidden" 或 "disabled" 才能触发 onload;设成 "showing" 会报错,因为没渲染目标。
VTT 文件里可以写 JSON 片段,但需确保 UTF-8 编码且无 BOM;更稳妥的做法是用纯文本每行一个键值对,JS 用 track.track.kind === "metadata" 过滤后解析。
别指望它兼容移动端:iOS Safari 加载 metadata 轨道时,track.readyState 常卡在 0,得监听 load 事件而非轮询状态。
真正容易被忽略的,是 kind 值必须字面量匹配、大小写敏感、不可拼错——"subtitle"、"subtitles "(尾部空格)、"Subtitles"(大写 S)全都会被浏览器当作非法值静默丢弃,连 video.textTracks 列表里都不会出现。
kind="metadata" 不触发任何 UI,也不依赖 WebVTT 格式——它可以指向任意文本资源,只要响应头是 text/plain 或 application/json(注意:浏览器仍要求同源或 CORS)。
它的用途是让脚本读取结构化数据,比如章节元信息、广告位时间点、互动热点坐标。
track.mode 必须设为 "hidden" 或 "disabled" 才能触发 onload;设成 "showing" 会报错,因为没渲染目标。
VTT 文件里可以写 JSON 片段,但需确保 UTF-8 编码且无 BOM;更稳妥的做法是用纯文本每行一个键值对,JS 用 track.track.kind === "metadata" 过滤后解析。
别指望它兼容移动端:iOS Safari 加载 metadata 轨道时,track.readyState 常卡在 0,得监听 load 事件而非轮询状态。
真正容易被忽略的,是 kind 值必须字面量匹配、大小写敏感、不可拼错——"subtitle"、"subtitles "(尾部空格)、"Subtitles"(大写 S)全都会被浏览器当作非法值静默丢弃,连 video.textTracks 列表里都不会出现。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











