as

Settings
Sign out
Notifications
Alexa
亚马逊应用商店
Ring
AWS
文档
Support
Contact Us
My Cases
新手入门
设计和开发
应用发布
参考
支持

在Vega中实现隐藏式字幕和字幕

在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);

contentUricontentMimeType参数不是标准W3C参数。

支持以下MIME类型。

  • application/ttml+xml
  • text/vtt
  • application/x-subtitle
  • application/x-subtitle-sami
  • application/x-subtitle-tmplayer
  • application/x-subtitle-mpl2
  • application/x-subtitle-dks
  • application/x-subtitle-qttext
  • application/x-subtitle-lrc
  • application/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设备或模拟器上构建并运行您的应用:

  1. 导航到播放视频的屏幕。
  2. 开始播放包含字幕的媒体。
  3. 验证屏幕上是否显示字幕。
  4. 测试在不同字幕轨道之间的切换(如果有)。

已知限制

  • 不支持字幕的垂直渲染。
      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日