You need to enable JavaScript to run this app.
导航
外挂字幕
最近更新时间:2025.09.01 11:34:48首次发布时间:2025.09.01 11:34:48
复制全文
我的收藏
有用
有用
无用
无用

外挂字幕是指字幕文件与视频文件分开存储,用户在播放视频时按需导入字幕文件。React Native SDK 支持配置外挂字幕、切换字幕及字幕显示与加载的相关回调。

前提条件

  • 外挂字幕为高级版或企业版功能。请确保您已购买高级版或企业版 License,购买方式详见播放器 License
  • 如果您通过 Vid 方式播放视频,需要准备字幕文件:
    • 如果您已有单独的字幕文件,可将字幕文件上传至视频点播服务并与 Vid 绑定。具体请见上传字幕文件并绑定 Vid
    • 如果您没有单独的字幕文件,可通过视频点播媒体处理服务生成字幕文件。具体请见智能生成字幕文件

开启外挂字幕功能

  1. 创建播放器后,调用 enableSubThread 方法开启播放器的字幕总开关,提升字幕加载性能。

    const player = await initPlayer({viewId: 'player'});
    
    // 字幕总开关
    player.enableSubThread(true);
    
  2. 调用 enableSubtitle 方法开启或关闭字幕解析。开启后,播放器将解析字幕并通过回调返回数据。如果传入 false,则播放器停止解析字幕,字幕回调也将停止触发。您可以使用此方法作为字幕显示的开关。

    // 字幕解析开关
    player.enableSubtitle(true);
    

设置字幕源

播放器 SDK 支持以下两种方式设置字幕源。您可根据实际情况选择。

说明

若您需要预渲染外挂字幕,推荐在预渲染回调 onPlayerCreated 中进行。也推荐在 onPlayerCreated 中添加预渲染播放器的字幕回调。

使用 DirectURL 方式

应用服务端下发字幕地址,客户端按照字幕信息说明组建字幕数据,再调用 setSubDesInfoModel 方法设置字幕信息。

import { createDirectUrlSource } from '@volcengine/react-native-vod-player';

// 组建字幕数据
const subtitleInfo = {
  list: [
    {
      id: 1,
      language: 'cmn-Hans-CN',
      language_id: 1,
      url: 'https://demo.com/e87a83***961e?auth_key=17607***xt_plain',
      format: 'webvtt',
      sub_id: 1,
    },
    {
      id: 2,
      language: 'eng-US',
      language_id: 2,
      url: 'https://demo.com/e87a83***00eb0a6f3432e?auth_key=1760759306-****lain',
      format: 'webvtt',
      sub_id: 2,
    },
  ],
};
const source = createDirectUrlSource({
  vid: 'v0d032g1***5q6nkalr3ig',
  url: 'https://demo.com/9fc0da***7e97a10b7f9ca7?a=0&auth_key=1760758121-422b49c****w%3D%3D&vl=&vr=',
  cacheKey: 'v0d032g1***alr3ig',
});
player.setVideoSource(source);
// 设置字幕信息
player.setSubDesInfoModel(subtitleInfo);

使用 Vid + SubtitleToken 方式

您需在应用服务端使用视频点播服务端 SDK 签发临时播放 Token 和字幕鉴权 Token,然后在客户端调用 setSubtitleAuthToken 方法设置字幕源。详见签发字幕鉴权 Token

import { createVidSource } from '@volcengine/react-native-vod-player';

// 视频 vid
const vid = 'videovid';
// 由服务端签发的临时播放 Token
const playAuthToken = 'playAuthToken';
// 创建播放源
const source = createVidSource({
  vid,
  playAuthToken,
  cacheKey: vid,
});
// 设置播放源
player.setVideoSource(source);
// 设置用于字幕获取的 subAuthToken
player.setSubtitleAuthToken(subtitleToken);

说明

生成 playAuthTokensubAuthToken 和调用 createVidSource 方法创建播放源时所用的 Vid 必须保持一致,否则会导致解析错误。

设置字幕回调

调用 setSubtitleCallback 设置字幕回调来更新字幕状态及字幕显示内容。

player.setSubtitleCallback({
  // 字幕信息回调,用于更新显示字幕
  onSubtitleInfoCallback(subInfo) {
    console.log(`subtitle update to ${subInfo.content}`);
  },
  onSubtitleInfoRequested(jsonInfo: string, error?: Error) {
    // 针对 Vid 播放,当请求到字幕时播放器回调,此时可以调用 getSubtitleIDs 获取字幕 ID 列表
    if (!error) {
      const ids = player.getSubtitleIDs();
      if (ids && ids.length) {
        // 切换到第一个字幕
        player.switchSubtitleById(ids[0]);
      }
    }
  },
  onSubLoadFinished(success: boolean) {
    // 当前字幕加载完成
    console.log(`current subtitle load ${success ? 'success' : 'fail'}`);
  },
  onSubSwitchCompleted(success: boolean, id: number) {
    // 字幕切换完成,currentLangId:当前语言 ID
    console.log(`subtitle ${id} switch ${success ? 'success' : 'fail'}`);
  },
});

其中最重要的回调是 onSubtitleInfoCallback。该回调会在字幕随播放进度发生变化时触发,包括字幕清除。您需根据回调的 subInfo 信息更新显示的字幕。subInfo 包含以下信息:

  • content:字幕内容。
  • duration:该段字幕持续时间。
  • pts:该段字幕对应的视频播放时间。

以下为在 React Native 组件中更新显示字幕的示例代码:

import {useState} from 'react';

// ....

const [curText, setCurText] = useState('');
const [enableSub, setEnableSub] = useState(true);

player.setSubtitleCallback({
  onSubtitleInfoCallback(subInfo) {
    // 字幕信息回调,用于更新显示字幕
    setCurText(subInfo.content)
  },
});

// ....

return (
    <View>
      {enableSub && (
          <View style={[styles.sub]}>
            <Text>{curText}</Text>
          </View>
      )}
    </View>
)

切换字幕

可通过 getSubtitleIDs 获取字幕 ID 列表,再调用 switchSubtitleById 传入字幕 ID 进行字幕切换。

// 获取字幕 ID 列表
const ids = player.getSubtitleIDs();
// 切换字幕
player.switchSubtitleById(ids[0]);

如果要设置起播的默认字幕,则可在调用 play 前调用 switchSubtitleById 设置字幕 ID。

Vid 模式下渲染字幕切换列表 UI

字幕回调 onSubtitleInfoRequested 中的 jsonInfo 参数为一个 JSON 字符串。解析该字符串后,所得对象的 list 属性为一个数组,数组中的每一项均为 SubDesInfoModel 类型。每项的具体数据类型如下,各字段的含义详见字幕信息说明

{
  id: number,
  language: string,
  language_id: number,
  url: string,
  format: string,
  sub_id: number,
}

您可基于此列表数据渲染字幕列表 UI:

onSubtitleInfoRequested(jsonInfo: string, error?: Error) {
    // 针对 Vid 播放,当请求到字幕时播放器回调,此时可以调用 getSubtitleIDs 获取字幕 ID 列表
    if (!error) {
      try {
        // 解析 jsonInfo
        const json = JSON.parse(jsonInfo);
        // 渲染字幕列表 UI
        setVidSubList(json.list);
      } catch (err) {
        console.error(err);
      }
    }
},

外挂字幕预加载

为提升用户观看视频时字幕的加载速度和成功率,您可结合视频预加载策略,在设置预加载视频源的同时,为每个视频源关联一个需要提前加载的外挂字幕文件。

注意

只能预加载一个字幕源。

根据播放源类型的不同,配置方式如下:

DirectUrl 播放源

对于 DirectUrl 源,您需要在创建播放源时提供完整的字幕列表,并明确指定要预加载哪一个。调用 createDirectUrlSource 创建播放源时,传入以下两个关键参数:

  • subtitleInfoModel: 包含所有可用字幕信息的完整对象。
  • subtitleId: 您希望预加载的那个字幕的 sub_id
import { createDirectUrlSource } from '@volcengine/react-native-vod-player';

const subtitleInfo = {
  list: [
    { language: 'cmn-Hans-CN', language_id: 1, url: '...', format: 'webvtt', sub_id: -987900477 },
    { language: 'eng-US', language_id: 2, url: '...', format: 'webvtt', sub_id: 1868145343 },
  ],
};

const urlSource = createDirectUrlSource({
    vid: 'your_vid_1',
    url: 'https://example.com/video.mp4',
    cacheKey: 'your_cache_key_1',
    // 1. 提供完整的字幕列表
    subtitleInfoModel: subtitleInfo,
    // 2. 指定你想预加载的那个字幕的 ID (这里选择英语字幕)
    subtitleId: 1868145343, 
});

// 将配置好的视频源加入预加载任务列表
setStrategySources([urlSource, /* other sources */]);

在播放该视频时,您需要先设置相同的字幕信息,然后切换到预加载时指定的字幕 ID。

// 开启字幕功能
player.enableSubThread(true);
player.enableSubtitle(true);

// 1. 必须传入与预加载时相同的 subtitleInfoModel
player.setSubDesInfoModel(subtitleInfo);

// 2. 切换到预加载时指定的 subtitleId
player.switchSubtitleById(1868145343);

Vid 播放源

对于 Vid 源,由于字幕列表是动态请求的,预加载的配置流程有所不同。您需要先指定一个目标语言,然后播放器会在获取到字幕列表后,自动预加载匹配该语言的字幕。创建 Vid 源时,除了 playAuthToken,还需传入 subtitleAuthToken

import { createVidSource } from '@volcengine/react-native-vod-player';

const vidSource = createVidSource({
   vid: 'your_vid_2',
   playAuthToken: 'your_play_auth_token',
   subtitleAuthToken: 'your_subtitle_auth_token',
});

在启动预加载任务前,通过以下函数告知预加载模块您希望优先加载哪种语言的字幕。

  • setDefaultPreloadTaskFeature(languageId):设置目标字幕的语言 ID。预加载模块会寻找与此 ID 匹配的字幕进行下载。如果找不到,则会默认选择字幕列表中的第一个。
  • setPreloadTaskFactory():应用设置并启动预加载任务。
// 设置预加载的目标字幕语言为英语 (language_id = 2)
setDefaultPreloadTaskFeature(2);

// 启动预加载任务
setPreloadTaskFactory();

// 您也可以在后续动态更新目标语言
// setDefaultPreloadTaskFeature(1); // 更新为中文

播放视频时,您需要在字幕信息回调中,找到与您在步骤 2 中设置的语言 ID 相匹配的字幕,并主动切换过去。

// 开启字幕功能
player.enableSubThread(true);
player.enableSubtitle(true);

// 设置字幕请求所需的 token
player.setSubtitleAuthToken('your_subtitle_auth_token');

// 设置字幕回调,以在获取到列表后执行切换
player.setSubtitleCallback({
  onSubtitleInfoRequested: (jsonInfo, error) => {
    if (error) {
      console.error('Failed to request subtitle info:', error);
      return;
    }
    
    const data = JSON.parse(jsonInfo);
    // 假设在预加载时设置了 language_id 为 2 (英语)
    const targetLanguageId = 2; 
    
    // 查找与预加载时语言 ID 匹配的字幕
    const targetSub = data.list.find((s: any) => s.language_id === targetLanguageId);
    
    if (targetSub) {
      // 切换到目标字幕,此时会优先使用已缓存的数据
      player?.switchSubtitleById(targetSub.sub_id);
    }
  },
});

验证预加载是否成功

无论使用哪种播放源,您都可以通过监听 onSubtitleHitCacheChange 事件来确认字幕是否成功命中了预加载缓存。

player.setListener({
  onSubtitleHitCacheChange: (subtitleKey, subCacheSize) => {
    if (subCacheSize > 0) {
        console.log(`Subtitle cache hit! Key: ${subtitleKey}, Size: ${subCacheSize} bytes`);
    }
  },
});

预加载的执行会受到当前网络状况、设备性能和播放器缓冲策略的影响。在切换到下一个视频时,如果对应的预加载任务尚未完成,播放器仍会正常在线请求字幕文件,不影响字幕的最终播放,只是无法享受预加载带来的加速效果。