是W3C指定的无障碍音频描述方案,但仅Safari+VoiceOver等少数环境支持;稳定旁白需用配合JS控制独立audio播放。

track 元素本身不支持旁白(aria-label 或语音合成)
HTML 的 <track></track> 是为视频/音频提供**字幕、章节、描述性文本(descriptions)** 的,它不直接触发屏幕阅读器朗读,也不等同于“旁白解说”。所谓“旁白解说”,实际需要的是:在用户播放媒体时,由辅助技术(如 NVDA、VoiceOver)主动读出的同步语音内容。而 <track kind="descriptions"></track> 才是唯一被 W3C 明确用于提供**无障碍音频描述**的类型——但它依赖浏览器+屏幕阅读器对 descriptions 轨道的支持,目前仅 Safari + VoiceOver 和部分 Edge 场景有基础实现,Chrome 和 Firefox 基本不激活该轨道。
真正可行的旁白方案:用 JavaScript 控制 audio + track 同步
绕过浏览器对 descriptions 轨道的弱支持,自己管理语音播放才是稳定做法。核心思路是:把旁白录成独立 .mp3,用 <audio></audio> 播放;再通过 <track kind="metadata"></track> 提供时间点标记(cue),用 JS 监听 timeupdate 触发对应旁白片段。
实操建议:
-
<track kind="metadata" src="cues.vtt"></track>中的cues.vtt文件需按 WebVTT 格式写时间轴和自定义数据,例如:WEBVTT <p>00:00:01.000 --> 00:00:03.500 {"action":"play","audio":"intro.mp3"}</p><p>00:00:05.200 --> 00:00:08.100 {"action":"play","audio":"button-desc.mp3"} - 监听
video.addEventListener('timeupdate', ...),解析当前时间落在哪个 cue 区间,然后调用new Audio(src).play()播放对应音频 - 注意:自动播放受策略限制,首次交互(如点击“开始教学”)后才能触发音频;建议用
audio.play().catch(e => console.warn("Audio blocked:", e))捕获静音或拦截 - 避免多个旁白重叠:每次触发前先
if (currentAudio) currentAudio.pause()
为什么不用 kind="captions" 或 kind="subtitles" 做旁白?
因为这两类 track 专为视觉呈现设计,浏览器不会将其内容送入语音通道。即使你把文字写成“请现在点击右上角的设置按钮”,屏幕阅读器也不会自动读——除非用户手动聚焦到字幕区域(且多数用户根本不会这么做)。它们解决的是「看不清」问题,不是「听不见」或「需额外解释」问题。
立即学习“前端免费学习笔记(深入)”;
容易踩的坑:
- 误以为给
<track kind="subtitles"></track>加sr-only类就能让屏幕阅读器读——不行,字幕轨道默认不暴露给 ARIA - 在
<track></track>的label属性里写说明文字(如label="旁白解说")——这只是菜单显示名,不触发语音 - 依赖
kind="descriptions"且不做降级:一旦用户用 Chrome,整个旁白功能就失效,无任何 fallback 提示
复杂点在于时间精度与多端一致性
WebVTT cue 时间戳受浏览器渲染帧率、JS 主线程阻塞、音频解码延迟影响,timeupdate 事件并非每毫秒触发,实际误差常达 ±100ms。这意味着旁白可能比画面晚半拍,尤其在低端设备或页面卡顿时更明显。不要追求 10ms 级同步;优先保证关键操作点(如“点击此处展开代码”)的旁白可被清晰听到,而不是死磕起始毫秒数。如果教学内容允许,把旁白音频本身留 200ms 前导静音,比硬压 JS 时间逻辑更可靠。



















