尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
dash.js 自定义 WebVTT 字幕渲染(Custom WebVTT Rendering)完整指南:基于 vtt.js 的手动渲染与 cue 控制
音视频前端【免费下载链接】dash.jsA reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.项目地址https://gitcode.com/gh_mirrors/da/dash.js点击查看免费下载dash.js 默认使用浏览器原生 APItrack元素与TextTrack渲染 WebVTT 字幕。本文介绍如何通过customRenderingEnabled设置启用基于vtt.js库的自定义渲染管线将字幕渲染到开发者自行控制的 HTMLdiv容器中从而在设备原生不支持 VTT 的情况下获得字幕能力并对 cue 的渲染时机、样式与生命周期实现完全掌控。读完本文你将掌握设置项配置、渲染容器挂载、vtt.js引入方式、完整可运行示例以及 dash.js 源码中手动 cue 处理manualCueProcessing、cue 进入/退出事件派发等底层机制。为什么需要自定义 WebVTT 渲染dash.js 的字幕文本轨道渲染分为两类路径原生渲染默认WebVTT cue 被解析后写入视频元素的原生TextTrack由浏览器负责排版与显示。这种方式简单可靠但渲染细节字体、位置、样式、显示时机完全交由浏览器决定且要求浏览器原生支持 WebVTT。自定义渲染本文主题开启customRenderingEnabled后dash.js 不再把 VTT cue 交给原生TextTrack而是改用vtt.js库解析 cue并借助开发者提供的 HTMLdiv容器手动渲染。这带来两个直接收益补齐能力在缺乏原生 VTT 支持的设备/浏览器上也能渲染字幕vttjs.html 示例说明中明确写道This enables VTT support on devices that do not provide native VTT support。更多控制权渲染容器的布局、层级、样式由开发者完全自定义配合dispatchForManualRendering还可以把 cue 的进入/退出以事件形式派发出来实现完全的自有渲染逻辑。需要留意的是该特性仅针对分片式 WebVTT 文本轨道非嵌入式字幕例如 CEA/608 嵌入式字幕仍走原生渲染路径这一点在 TextTracks.js 的窗口更新逻辑中有明确体现。三步启用自定义 WebVTT 渲染第 1 步开启 customRenderingEnabled 设置项在player.updateSettings()中开启streaming.text.webvtt.customRenderingEnabledplayer.updateSettings({ streaming: { text: { webvtt: { customRenderingEnabled: true } } } })该设置项的默认值为false定义于 Settings.jswebvtt: { customRenderingEnabled: false }其语义注释位于 Settings.js开启后 dash.js 将对 WebVTT 字幕采用自定义渲染需要引入位于contrib目录的外部库vtt.js。第 2 步添加渲染容器在视频元素附近或视频之上放置一个用于承载字幕的div。容器需要足够的宽高来容纳 cue且通常应叠加在视频区域之上video preloadauto muted/video div styleposition: relative div idvtt-rendering-div stylemin-width: 600px; min-height: 100px;/div /div实践中vttjs.html 示例使用了一个定位在视频底部的叠加层并通过pointer-events: none避免遮挡鼠标操作div classsample-video-wrapper idvideo-wrapper video preloadauto muted/video div idvtt-rendering-div styleposition:absolute; bottom:0; left:0; width:100%; height:30%; pointer-events:none; z-index:1;/div /div提示attachVttRenderingDiv()只负责记录容器引用不会像attachTTMLRenderingDiv()VideoModel.js那样自动为容器注入定位、flex 等内联样式因此容器的位置、尺寸与层级需要开发者自行定义对照可见 setVttRenderingDiv 仅做简单赋值。第 3 步将容器挂载到播放器调用player.attachVttRenderingDiv(div)把渲染容器交给 dash.jslet vttRenderingDiv document.querySelector(#vtt-rendering-div); player.attachVttRenderingDiv(vttRenderingDiv)该方法定义于 MediaPlayer.js若在调用attachView()之前调用会抛出ELEMENT_NOT_ATTACHED_ERROR成功后调用videoModel.setVttRenderingDiv(div)保存容器引用。此后 TextTracks.js 在createTracks()阶段会通过videoModel.getVttRenderingDiv()取回该容器作为手动渲染的挂载点vttCaptionContainer。第 4 步引入 vtt.js 库自定义渲染依赖vtt.jsVideo.js 的 WebVTT 解析/渲染引擎。dash.js 仓库的contrib目录已内置该库contrib/videojs-vtt.js/vtt.min.js 及其未压缩版 contrib/videojs-vtt.js/vtt.js在 HTML 中引入即可script src../../contrib/videojs-vtt.js/vtt.min.js/script引入后全局会暴露window.WebVTT含WebVTT.Parser、WebVTT.processCues、WebVTT.StringDecoder等 API。dash.js 正是通过检测这些 API 来初始化自定义解析器见 VttCustomRenderingParser.jsif (window window.WebVTT window.WebVTT.Parser) { vttjs new window.WebVTT.Parser( window, window.vttjs, window.WebVTT.StringDecoder() ); }若vtt.js未加载自定义解析器创建失败异常被静默捕获而 TextSourceBuffer.js 的解析器选择逻辑会回退到内置的vttParser因此务必保证脚本引入顺序在 dash.js 之前示例中vtt.min.js位于dash.all.debug.js之前加载。完整示例vttjs.html仓库中提供了开箱即用的完整示例 samples/captioning/vttjs.html其核心初始化逻辑如下var player dashjs.MediaPlayer().create(); player.updateSettings({ debug: { logLevel: 5 }, streaming: { text: { webvtt: { customRenderingEnabled: true } } } }) player.initialize(video, url, true); player.attachVttRenderingDiv(wrapper.querySelector(#vtt-rendering-div));示例使用 Akamai 的带字幕 DASH 流Elephants Dream 测试片首个字幕约在 15 秒处出现。注意示例说明中的提醒This sample will only work when using http as the subtitles are not hosted via https——即该测试流的字幕资源未通过 HTTPS 托管本地以 http 方式打开示例页面才能正常工作。底层机制自定义渲染是如何工作的解析阶段选择 vtt.js 解析器在 TextSourceBuffer.js 的_getParser(codecType)中当媒体类型为 VTT 且开启了自定义渲染且自定义解析器存在时选用vttCustomRenderingParserparser settings.get().streaming.text.webvtt.customRenderingEnabled vttCustomRenderingParser ? vttCustomRenderingParser : vttParser;VttCustomRenderingParserVttCustomRenderingParser.js在parse(data)中注册oncue回调把vtt.js解析出的每个 cue 转换成 dash.js 内部 cue 结构并额外保留stylesalign、line、position、size等与datacue 文本供后续手动渲染使用vttjs.oncue function (cue) { cue.start cue.startTime; cue.end cue.endTime; cue.data cue.text; cue.styles { align: cue.align, line: cue.line, position: cue.position, size: cue.size } cues.push(cue); };渲染阶段手动 cue 处理与 vtt.js 的 processCues开启自定义渲染后TextController.js 在每次PLAYBACK_TIME_UPDATED事件中调用tracks.manualCueProcessing(e.time)同时针对PLAYBACK_SEEKING事件注册处理TextController.js在 seek 时调用disableManualTracks()清理旧的激活 cueTextTracks.js。manualCueProcessing(time)TextTracks.js的核心逻辑找出所有处于手动显示模式manualMode TEXT_SHOWING的活动轨道用时间点time在 cue 区间树CueIntervalTree中查出当前应激活的 cue 集合计算cuesToExit退出与cuesToEnter进入两个差集对退出的 cue移除其在vttCaptionContainer中对应的 DOM 节点_removeManualCue见 TextTracks.js按cue.cueID匹配并删除子节点对进入的 cue调用WebVTT.processCues(window, [cue], vttCaptionContainer, cue.cueID)TextTracks.js由vtt.js完成 cue 的样式排版与 DOM 插入。updateTextTrackWindow()TextTracks.js中也会跳过开启了自定义渲染的 VTT 轨道if (!trackInfo.isEmbedded customVttRenderingEnabled) continue;避免与原生 TextTrack 更新逻辑冲突确保这些 cue 只走手动渲染路径。事件派发dispatchForManualRendering自定义渲染还有一个可选的进阶开关streaming.text.dispatchForManualRendering默认false见 Settings.js。其语义Settings.js为开启后 dash.js 将不再自行显示字幕而是派发CUE_ENTER/CUE_EXIT事件把 cue 的进出完全交给应用层处理。在manualCueProcessing中TextTracks.js该开关控制分支行为cuesToExit.forEach((cue) { if (settings.get().streaming.text.dispatchForManualRendering) { _triggerCueExit(cue); // 派发 cueExit 事件 } else { _removeManualCue(cue); // 从容器中移除 DOM } }); cuesToEnter.forEach((cue) { if (settings.get().streaming.text.dispatchForManualRendering) { _triggerCueEnter(cue); // 派发 cueEnter 事件 } else { WebVTT.processCues(window, [cue], vttCaptionContainer, cue.cueID); } });事件通过_triggerCueEnter/_triggerCueExitTextTracks.js触发MediaPlayerEvents.CUE_ENTERcueEnter与CUE_EXITcueExit事件事件名定义见 MediaPlayerEvents.js。这意味着你可以监听这些事件用自己的渲染方案如自定义 DOM、Canvas、样式化 cue替代vtt.js的默认排版player.on(dashjs.MediaPlayer.events.CUE_ENTER, function (e) { // 自定义渲染读取 cue 的 start/end/data/styles 自行绘制 }); player.on(dashjs.MediaPlayer.events.CUE_EXIT, function (e) { // 自定义清理 });配置速查表设置项类型默认值作用streaming.text.webvtt.customRenderingEnabledbooleanfalse开启基于 vtt.js 的 WebVTT 自定义渲染需配合attachVttRenderingDiv()与contrib/videojs-vtt.js库streaming.text.dispatchForManualRenderingbooleanfalse开启后不再由 dash.js 渲染字幕改为派发CUE_ENTER/CUE_EXIT事件由应用自行渲染streaming.text.defaultEnabledbooleantrue字幕是否默认启用见 Settings.jsstreaming.text.extendSegmentedCuesbooleantrue分段 cue 是否通过扩展结束时间合并为单个 cue见 Settings.js调试与常见问题字幕未显示首先确认vtt.min.js已在 dash.js 之前加载window.WebVTT必须存在其次确认customRenderingEnabled在初始化播放前已通过updateSettings()设置最后确认渲染div有足够的宽高且未设置display: none或遮挡层级问题。调用 attachVttRenderingDiv 抛错ELEMENT_NOT_ATTACHED_ERROR表示尚未调用player.attachView()或初始化视频元素请先完成视图挂载。示例无法加载字幕vttjs.html 的测试流字幕未通过 HTTPS 托管需通过 http 协议打开示例页面或更换为自身可用的 https 字幕流。嵌入式字幕不受影响CEA-608 等嵌入式字幕不参与该自定义渲染路径仍由原生机制处理见 TextTracks.js 的排除条件。小结自定义 WebVTT 渲染是 dash.js 字幕体系中的重要扩展点通过customRenderingEnabledattachVttRenderingDiv()vtt.js三要素可以在缺乏原生 VTT 支持的平台上获得字幕能力配合dispatchForManualRendering与CUE_ENTER/CUE_EXIT事件还能完全接管 cue 的渲染实现。相关源码入口MediaPlayer.js 的 attachVttRenderingDiv、TextController.js 的手动 cue 调度、TextTracks.js 的 manualCueProcessing、VttCustomRenderingParser.js以及可运行的完整示例 samples/captioning/vttjs.html。赞分享音视频前端【免费下载链接】dash.jsA reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.项目地址https://gitcode.com/gh_mirrors/da/dash.js点击查看免费下载相关推荐FilmCraft 字幕系统字幕轨道、SRT/WebVTT/SCC 文件导入导出与 Burn-in 渲染实现FilmCraft 字幕系统字幕轨道、SRT/WebVTT/SCC 文件导入导出与 Burn in 渲染实现 本文以 docs/captions.md httSoup导出GGUF完全教程一键转Ollama/llama.cpp可用的量化模型Soup导出GGUF完全教程一键转Ollama/llama.cpp可用的量化模型 Soup 是一个「一份 YAML 搞定大模型微调」的开源工具除了训练它还人工智能大模型微调LoRACLIBackbone.Marionette 视图模板渲染View Template Rendering完全指南模板定义、渲染器定制与数据序列化Backbone.Marionette 视图模板渲染View Template Rendering完全指南模板定义、渲染器定制与数据序列化 Marione前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

AI编程项目防失控:三层防御体系与完成标准

AI编程项目防失控:三层防御体系与完成标准

1. 先说说我见过的最常见的“AI项目死亡路径” 1.1 前四周:所有功能三天就上线 我在模拟项目X上负责一个内部工具从零到一的搭建,目标是让运营团队能在后台完成数据对账和异常预警。最初四周,开发速度快得不太真实:界面、接口、数…

📅 2026/10/13 13:54:48
Hive分区表导入txt文件的5种方法与避坑指南

Hive分区表导入txt文件的5种方法与避坑指南

1. 项目概述:为什么一个txt文件导入Hive分区表,值得花一整篇干货来写?“txt文件导入到hive分区表中”——这行字看起来平平无奇,甚至有点过时。在大家动辄谈Flink实时入湖、Delta Lake自动合并、Iceberg时间旅行的今天&#xff0c…

📅 2026/10/13 13:54:48
基于EEG的情绪分类:SVM在DEAP与SEED-IV上的可行路线

基于EEG的情绪分类:SVM在DEAP与SEED-IV上的可行路线

简介:基于 DEAP 与 SEED-IV 数据库的 EEG 情绪检测研究论文,聚焦二维情绪模型下的内心情绪识别,适合脑机接口、情感计算方向的在校生及科研人员参考。文中采用离散小波变换提取五个频段,从功率、能量、微分熵和时域等维度构造特征…

📅 2026/10/13 13:54:48
MORE NEWS

更多资讯

📰

STM32F103纸张厚度实时计数系统:电赛F题闭环实现

简介:本资源是2019年全国大学生电子设计竞赛F题「纸张计数装置」的完整嵌入式实现方案,面向STM32初学者、电赛备赛学生及电容传感应用实践者,解决高精度非接触式纸张动态计数这一典型工程问题。压缩包含222个文件,以42个C源文件&a…

📰

AI率检测到底查什么?八类降AI率方案实测与避坑指南

2026年刚开年,不少专科院校的期末评阅环节突然多了一道硬性流程:提交课程报告、实训总结、毕业设计说明之前,导师会先用某种AI内容检测系统跑一遍。我见过好几个同学明明是自己熬夜写的初稿,只因为框架比较规范、用词比较正式&…

📰

CEEMD源码实战:模态混叠修复与参数调优指南

简介:CEEMD(完全集合经验模态分解)源代码压缩包,面向从事非线性、非平稳信号分析的工程与科研人员,用于解决传统EMD存在模式混合、虚假极值等问题。CEEMD作为EMD的改进版本,通过集合平均策略有效抑制模态混…

📰

7800张YOLO数据集:埃及伊蚊吸血行为检测实战全解析

如果你研究蚊媒传染病,或者正在做病媒生物监测相关的视觉项目,那么“埃及伊蚊吸血行为检测数据集”这个标题你应该能一眼看出它的分量。这套数据集的表面形式是“7800张YOLO格式的昆虫图片”,但往深了说,它其实是把“蚊虫吸血行为…

📰

bk-cmdb count_biz_host_cpu 接口详解:按业务统计主机 CPU 数量的成本管理专用 API

后端企业应用运维 【免费下载链接】bk-cmdb 蓝鲸智云配置平台(BlueKing CMDB) 项目地址: https://gitcode.com/gh_mirrors/bk/bk-cmdb 点击查看 免费下载 本文围绕 bk-cmdb 配置平台(BlueKing CMDB)的 count_biz_host_cpu 接口展开&#xff…

📰

Farm 示例测试指南:用 test-examples 与 test-e2e 精确验证单个示例

前端构建构建工具开发工具 【免费下载链接】farm Extremely fast Vite-compatible web build tool written in Rust 项目地址: https://gitcode.com/gh_mirrors/fa/farm 点击查看 免费下载 Farm 是一个用 Rust 编写的现代 Web 构建工具,仓库通过 exampl…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬