在Vega中实现隐藏式字幕和字幕
在本文中,您将使用符合W3C的文本跟踪API在Vega应用中实现隐藏式字幕和字幕。隐藏式字幕提供音频转录,以帮助残障或有环境噪音的观众,而字幕则将对话翻译成不同的语言。文本轨道大致可以分为两类:
- 带内: 在媒体区段内提供的文本轨道,例如CEA字幕和MP4文本轨道(WebVTT/TTML作为单独的轨道)。
- 带外 (OOB): 文本轨道作为媒体流中的单独文件传送。在ABR流媒体中,这些文件会在播放列表或清单文件中引用。在某些情况下,字幕文件通过数据库与媒体内容相关联,不存在于清单文件中。
先决条件
- Vega开发环境已设置
- React Native和TypeScript的基础知识
@amazon-devices/react-native-w3cmedia程序包版本2.1.14或更高版本- Vega SDK v0.10或更高版本
添加所需的权限
要添加无障碍功能权限,请将以下内容添加到manifest.toml中。
[[wants.privilege]]
id = "com.amazon.devconf.privilege.accessibility"
安装VTTCue polyfill
@amazon-devices/react-native-w3cmedia程序包为VTTCue提供了polyfill,后者是TextTrackCue接口的实现。
在应用初始化期间安装polyfill。
import { VTTCue } from '@amazon-devices/react-native-w3cmedia';
// 在您的polyfill类中:
static install() {
console.log('正在安装W3CMedia polyfill');
global.window.VTTCue = global.VTTCue = VTTCue;
if(!window.VTTCue) {
console.log("VTTCue未进行polyfill处理");
}
}
添加KeplerCaptionsView组件
KeplerCaptionsView组件在屏幕上渲染隐藏式字幕和字幕。在使用VideoPlayer和AudioPlayer组件于预缓冲模式下运行时使用该组件。
将该组件添加到您的渲染树中。
import { KeplerCaptionsView } from '@amazon-devices/react-native-w3cmedia';
const onCaptionViewCreated = (captionsHandle: string): void => {
videoPlayer.setCaptionViewHandle(captionsHandle);
}
// 在组件的返回语句中:
<View style={{ backgroundColor: "white", alignItems: "stretch",
width: deviceWidth, height: deviceHeight}}>
<KeplerCaptionsView
onCaptionViewCreated={onCaptionViewCreated}
show={true}
style={{ width: '100%',
height: '100%',
top: 0,
left: 0,
position: 'absolute',
backgroundColor: 'transparent',
flexDirection: 'column',
alignItems: 'center',
zIndex: 2}}
/>
</View>
确保将show属性设置为true以渲染字幕。
为应用解析的字幕添加文本轨道
当您的应用直接处理字幕数据提取和解析时,请在HTMLMediaElement实现中添加一个文本轨道,并在其中填充VTTCue对象。此方法适用于您的应用解析的任何文本轨道,无论源是带内还是带外。如果您使用诸如Shaka播放器之类的JavaScript播放器,它会在内部管理轨道创建,您无需执行此步骤。
const textTrack = videoPlayer.addTextTrack('subtitles', 'SampleTextTrack', 'en');
向文本轨道添加线索
解析字幕数据后,使用VTTCue向文本轨道添加提示。
const vttCue = new VTTCue(startTime, endTime, payload);
vttCue.lineAlign = lineAlign;
vttCue.positionAlign = positionAlign;
if (size) {
vttCue.size = size;
}
textTrack.addCue(vttCue);
侦听原生解析的文本轨道
该平台会自动检测带内字幕,例如CEA 608和708。将媒体片段附加到SourceBuffer时,平台会在原生层中解析这些字幕,这比基于JavaScript的解析更有效。注册addtrack事件,以便在检测到文本轨道时接收通知。
videoPlayer.textTracks.addEventListener("addtrack", onTextTrackAdded);
const onTextTrackAdded = (event: Event): void => {
const textTrackList: TextTrackList | undefined | null = media.current?.textTracks;
if(textTrackList === undefined || textTrackList === null) {
return;
}
for (let i = 0; i < textTrackList.length; i++) {
const textTrack = textTrackList[i];
console.log(`文本轨道id = ${textTrack.id} \
kind = ${textTrack.kind} \
language = ${textTrack.language} \
label = ${textTrack.label} \
mode = ${textTrack.mode}`);
}
}
添加带有字幕文件URL的字幕
如果您的应用有字幕文件URL但缺少解析功能,则该平台可以提取、解析和渲染已知的字幕格式。添加文本轨道时传递字幕文件URL及其MIME类型。
这种方法不符合W3C,不是推荐的方法,并且正逐渐弃用。如果可能,改用应用端或基于JavaScript播放器的解析。
const textTrack = videoPlayer.addTextTrack("subtitles", 'SampleTextTrack', 'en',
contentUri, contentMimeType);
contentUri和contentMimeType参数不是标准W3C参数。
支持以下MIME类型。
application/ttml+xmltext/vttapplication/x-subtitleapplication/x-subtitle-samiapplication/x-subtitle-tmplayerapplication/x-subtitle-mpl2application/x-subtitle-dksapplication/x-subtitle-qttextapplication/x-subtitle-lrcapplication/x-subtitle-vtt
选择并显示文本轨道
将文本轨道模式设置为showing以在屏幕上渲染它。
textTrack.mode = 'showing';
默认情况下,添加文本轨道时模式设置为hidden。
使用ShakaPlayer自动解析字幕
ShakaPlayer可以自动解析和渲染清单文件和媒体片段中的字幕。使用ShakaPlayer时,播放器会在内部处理文本轨道的创建和提示管理,因此您无需手动调用addTextTrack() 或addCue()。
配置ShakaPlayer以启用文本轨道渲染。
shakaPlayer.configure({
autoShowText: shaka.config.AutoShowText.ALWAYS,
});
加载内容后,将文本轨道可见性设置为true以显示字幕。
async load(content: any) {
await shakaPlayer.load(content.uri);
shakaPlayer.setTextTrackVisibility(true);
}
确保您使用的是Vega SDK v0.21或更高版本,并且具有shaka-rel-v4.6.18-r2.5.tar.gz或更高版本的ShakaPlayer补丁。
测试实现
在Fire TV设备或模拟器上构建并运行您的应用:
- 导航到播放视频的屏幕。
- 开始播放包含字幕的媒体。
- 验证屏幕上是否显示字幕。
- 测试在不同字幕轨道之间的切换(如果有)。
已知限制
- 不支持字幕的垂直渲染。
const cue = new VTTCue(startTime, endTime, text); cue.vertical = ""; // 不支持“rl”或“lr” - 不支持自定义提示窗口大小。字幕窗口大小仅为自动。
const cue = new VTTCue(startTime, endTime, text); cue.size = 20; // 不支持自定义提示大小。 - 如果VTTCue中未提供位置,则字幕和隐藏式字幕将放置在屏幕底部以防止重叠。
- 不支持在同一个流程中使用多个
KeplerCaptionsView实例。 - 最多仅支持一个CEA 708原生轨道。
- 不支持原生字幕的滚动模式。有关更多详细信息,请参阅滚动字幕(仅提供英文版)。
- 原生字幕轨道不包含语言元数据。语言参数包含CC1、CC2、CC3和CC4等频道标识符。
- 不支持VTTRegion。
- 不支持字幕和隐藏式字幕的CSS样式。
常见问题解答
- 问: 如果平台支持原生CEA 608/708解析,应用是否需要解析带内字幕?
- 理想情况下,应启用CEA 608/708的原生解析,并应避免基于JavaScript的解析。只有当原生解析不起作用或应用需要访问标题文本时,应用才应解析字幕。
- 问: ShakaPlayer API不报告原生解析的字幕轨道。应用如何检测它们?
- 使用组合轨道管理策略:
- 对
subtitle轨道使用JavaScript播放器API(例如ShakaPlayer)。 - 对
caption轨道使用W3C媒体API中的VideoPlayer(MediaElement)。
以下示例使用这种方法查询所有可用的字幕。
getTextTracks(): TextTrackInfo[] { let textTrackInfoList: TextTrackInfo[] = []; if (this.player) { let shakaTextTrackList = this.player.getTextTracks(); for (let track of shakaTextTrackList) { textTrackInfoList.push({ id: 'shaka:' + track.id.toString(), kind: track.kind, language: track.language, label: track.label, mode: (track.active === true ? 'showing' : 'hidden'), playerTrackData: ({ type: 'shaka', track: track }), }); } } if (this.mediaElement) { let nativeTextTrackList = this.mediaElement.textTracks; for (let track of nativeTextTrackList) { if (track.label == 'Shaka Player TextTrack') { continue; } textTrackInfoList.push({ id: 'native:' + track.id.toString(), kind: track.kind, language: track.language, label: track.label, mode: track.mode, playerTrackData: ({ type: 'native', track: track }), }); } } return textTrackInfoList; } - 对
- 问: 如何启用或禁用文本轨道?
- 使用相同的组合轨道管理策略。以下示例显示如何选择文本轨道。
setTextTrack(newTrack: TextTrackInfo | null, currTrack: TextTrackInfo | null): void { if (currTrack) { if (currTrack.playerTrackData.type == 'native') { currTrack.playerTrackData.track.mode = 'hidden'; } else if (currTrack.playerTrackData.type == 'shaka') { this.player?.setTextTrackVisibility(false); } } if (newTrack) { if (newTrack.playerTrackData.type == 'native') { newTrack.playerTrackData.track.mode = 'showing'; } else if (newTrack.playerTrackData.type == 'shaka') { this.player?.selectTextTrack(newTrack.playerTrackData.track); this.player?.setTextTrackVisibility(true); } } } - 问: 启用由JavaScript播放器进行字幕解析会报告重复的文本轨道。如何避免这种情况?
- 依赖原生字幕解析时,禁用JavaScript播放器的带内字幕解析器,以防止重复的文本轨道。
要禁用ShakaPlayer的内嵌字幕解析功能,请取消注册媒体片段字幕解析器。
shaka.media.ClosedCaptionParser.unregisterParser('video/mp4'); shaka.media.ClosedCaptionParser.unregisterParser('video/mp2t');如果改用JavaScript带内解析,请使用JavaScript播放器API进行文本轨道管理:
- 使用
getTextTracks()检索可用的文本轨道。 - 使用
setTextTrackVisibility(isVisible)启用或禁用文本轨道。
- 使用
- 问: 是否支持字幕和隐藏式字幕样式?
- 可以。支持以下样式标签:
- 类别范围:文本颜色和文本背景颜色
- 斜体跨度
- 粗体跨度
- 下划线跨度
有关更多详细信息,请参阅WebVTT规范。
- 问: 是否支持VTTRegion?
- 不支持VTTRegion。
- 问: 是否支持字幕和隐藏式字幕的CSS样式?
- 不支持字幕和隐藏式字幕的CSS样式。
相关内容
Last updated: 2026年6月2日

