You need to enable JavaScript to run this app.
导航
添加外挂字幕
最近更新时间:2025.11.20 15:14:05首次发布时间:2023.11.09 11:10:28
复制全文
我的收藏
有用
有用
无用
无用

外挂字幕指与视频文件分离的字幕文件,用户可在播放时按需导入。播放器 SDK 支持添加 WebVTT (Web Video Text Tracks) 和 SRT (SubRip Text) 格式的外挂字幕。外挂字幕的优势在于其灵活性,用户可按需选择是否加载字幕以及加载何种语言的字幕,且无需进行视频转码,只需在播放端设置即可显示。本文介绍如何使用播放器 SDK 添加外挂字幕。

前提条件

  • 外挂字幕为高级版或企业版功能。请确保您已购买高级版或企业版 License,购买方式详见License 管理

    注意

    自 1.36.1 版本起,外挂字幕功能由增值服务调整至高级版和企业版。若您集成 1.36.1 之前的版本且想要使用此功能,请升级至最新版本。

  • 如果您通过 Vid 方式播放视频,需要准备字幕文件:
    • 如果您已有单独的字幕文件,可将字幕文件上传至视频点播服务并与 Vid 绑定。具体请见上传字幕文件并绑定 Vid
    • 如果您没有单独的字幕文件,可通过视频点播媒体处理服务生成字幕文件。具体请见智能生成字幕文件

核心流程说明

出于拓展性的考量,播放器 SDK 只返回字幕文本信息,具体的字幕展示需要您结合 UI 控件自行实现。实现外挂字幕功能的核心流程如下:

  1. 播放前配置:在播放器初始化后、调用 play 之前,通过 setOptionForKey 方法开启外挂字幕功能及相关优化项,然后设置字幕源(二选一:直接将字幕文件 URL 设置给播放器,适用于对起播速度有要求的场景,如短剧、短视频;与视频点播服务深度集成,开发简单,管理便捷),最后再调用 setSubtitleDelegate 注册监听器,以接收字幕内容。
  2. 播放中实现:在 onSubtitleInfoCallBack 回调中获取 SDK 按时间顺序推送的字幕文本,并将其渲染到您的 UI 控件(如 TextView)上。调用 setOptionForKey 控制字幕的显示与隐藏;调用 setOptionForKey 并传入目标语言的 sub_id 实现切换。
  3. (可选)进阶使用:
    • 字幕预加载:如需提升用户观看视频时字幕的加载速度和成功率,可结合视频预加载策略,在播放前提前缓存字幕文件。此功能需在预加载阶段就指定好视频源和字幕源。
    • 播放过程中动态添加字幕源。

API 调用时序

Image

开启外挂字幕功能

参考以下示例代码开启外挂字幕功能:

// 外挂字幕功能总开关,建议在设置 vid 之前调用
[self.videoEngine setOptionForKey:VEKeyPlayerEnableSubThread_BOOL value:@(YES)];
// 外挂字幕加载优化开关
// NO: 关闭外挂字幕加载优化;YES: 开启外挂字幕加载优化
[self.videoEngine setOptionForKey:VEKKeyPlayerSubtitleOptEnable_BOOL value:@(YES)];
// 使用数据加载模块 MDL 加载外挂字幕,提升加载成功率
// YES: 使用 MDL 加载外挂字幕
// NO: 不使用 MDL 加载外挂字幕
[self.videoEngine setOptionForKey:VEKKeySubTitleEnableMDL_BOOL value:@(YES)];

设置字幕源

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

使用 DirectURL 方式

使用 DirectURL 方式设置字幕源。您需要实现 TTVideoEngineSubDecInfoProtocol 协议构建字幕源。示例代码如下:

说明

若您需要将已经下载到本地设备的离线字幕文件作为字幕源,将 url 设为本地文件绝对路径即可,形如 file://xxxxx/xxx.srt

NSString *url = @"http://www.example.com/h264.mp4";
NSString *cacheKey = [url md5String]; // cacheKey 用作磁盘缓存的文件名,建议采用 URL 中能标识视频文件的部分的 MD5 值
TTVideoEngineUrlSource *source = [[TTVideoEngineUrlSource alloc] initWithUrl:url cacheKey:cacheKey];
[self.videoEngine setVideoEngineVideoSource: source];

// 设置 DirectURL 模式下的字幕源
// 该字幕源需要实现 TTVideoEngineSubDecInfoProtocol 协议
[self.videoEngine setSubDecInfoModel:self];
 

// MARK: - TTVideoEngineSubDecInfoProtocol
// 返回包含外挂字幕 URL 等信息的 JSON 字符串,详见本文 JSON 字幕信息说明章节
- (NSString *_Nullable)jsonString {
    return subtitleJSONStr;
}

// 返回字幕 list 包含的字幕数量
- (NSInteger)subtitleCount {
    return count;
}

使用 Vid + SubtitleToken 方式

使用 Vid + SubtitleToken 方式设置字幕源。示例代码如下:

说明

您可在应用服务端通过视频点播服务端 SDK 签发字幕鉴权 Token

NSString *vid = @"YOUR_VIDEO_ID"; // AppServer 下发
NSString *playAuthToken = @"YOUR_PLAYAUTHTOKEN"; // AppServer 下发
// resolution 为视频分辨率,例如:TTVideoEngineResolutionTypeHD
TTVideoEngineVidSource *vidSource = [[TTVideoEngineVidSource alloc] initWithVid:vid playAuthToken:playAuthToken resolution:TTVideoEngineResolutionTypeHD];
// 设置字幕鉴权 token,需在起播前设置
[self.videoEngine setSubtitleAuthToken:@"SUBTITLE_AUTHTOKEN"]; // AppServer 下发

// 设置默认展示语言。如不设置,SDK 会以点播服务端下发的顺序展示第一位语言
// 字幕语言映射表见:https://www.volcengine.com/docs/4/1186356
// 需传入 SubtitleID。SubtitleID 可通过 -[TTVideoEngine subtitleIDs] 获取。
[self.videoEngine setOptionForKey:VEKeyPlayerSwitchSubtitleId_NSInteger value:@(<#SubtitleID#>)];

[self.videoEngine setVideoEngineVideoSource:vidSource];
[self.videoEngine play];

设置字幕回调

在调用 play 播放前,调用 setSubtitleDelegate 设置字幕回调:

// 设置回调接收
[self.videoEngine setSubtitleDelegate:self];

字幕回调的具体使用说明如下:

/**
 * 字幕回调
 * <TTVideoEngineSubtitleDelegate>
 */
 // SDK 提供了多种字幕信息回调方法,以下列举核心的几种。推荐使用第二种 onSubtitleInfoCallBack 重载方法,因其提供了更丰富的字幕信息。
 // 方法一:仅返回字幕内容和时间戳
 - (void)videoEngine:(TTVideoEngine *)videoEngine onSubtitleInfoCallBack:(NSString *)content pts:(NSUInteger)pts {
     // 刷新字幕
     // 示例: [self.subtitleView refreshContent:content];
 }
 
 // 方法二:返回包含字幕内容、时间戳、持续时长等信息的 TTVideoEngineSubInfo 对象
 - (void)videoEngine:(TTVideoEngine *)videoEngine onSubtitleInfoCallBack:(TTVideoEngineSubInfo *)subInfo {
     // subInfo.pts: 字幕开始显示的时间戳
     // subInfo.content: 字幕内容
     // subInfo.duration: 字幕要持续的时长。
 }
 // 针对 Vid 播放,当请求到字幕时播放器回调,可以用来更新字幕列表,也可以用于设置默认字幕。适用于 1.47.3 及之后版本
- (void)videoEngine:(TTVideoEngine *)videoEngine onSubtitleInfoRequestFinish:(TTVideoEngineSubDecInfoModel *)subtitleInfoModel error:(NSError * _Nullable)error {
}
    // [videoEngine setOptionForKey:VEKeyPlayerSwitchSubtitleId_NSInteger value:@(<#SubtitleID#>)]; 设置默认字幕或切换字幕
}
 // 字幕切换完成,currentLangId:当前语言ID
- (void)videoEngine:(TTVideoEngine *)videoEngine onSubSwitchCompleted:(BOOL)success currentLangId:(NSInteger)currentLangId {
   
}

// 当前字幕加载完成
- (void)videoEngine:(TTVideoEngine *)videoEngine onSubLoadFinished:(BOOL)success info:(TTVideoEngineLoadInfo *)info {
   if (!success) {
       // 字幕加载失败。可移除字幕渲染或重新请求
   } else {
       // 字幕加载成功。
       // info.firstPts 字幕首次出现的时间戳
   }
}

// 自定义本地缓存字幕 cache key
- (NSString *)videoEngine:(TTVideoEngine *)videoEngine generateSubtitleCachKey:(NSString *)subTitleUrl extendInfo:(NSDictionary *)extendInfo {
 return nil;
}

控制字幕

开启/关闭字幕输出

参考以下示例代码在起播时或者播放过程中控制开启或者关闭字幕:

// 起播时或者播放过程中控制展示或者关闭字幕
// YES: 输出字幕;NO: 停止输出字幕
 [self.videoEngine setOptionForKey:VEKKeyPlayerSubEnabled_BOOL value:@(YES)];

切换字幕

参考以下示例代码传入字幕 ID 切换不同的字幕:

[self.videoEngine setOptionForKey:VEKeyPlayerSwitchSubtitleId_NSInteger value:@(<#NSInteger#>)];

说明

  • 使用 Vid 方式设置字幕源时,传入 SubtitleIdSubtitleId 可通过 -[TTVideoEngine subtitleIDs] 获取。
  • 使用 DirectURL 方式设置字幕源时,传入字幕信息 JSON 中的 sub_id 字段。

进阶使用

字幕预加载

为提升用户观看视频时字幕的加载速度和成功率,可结合视频预加载策略,在播放前提前缓存字幕文件。此功能需在预加载阶段就指定好视频源和字幕源。

说明

预加载阶段

DirectUrl 模式
  1. 参考文档开启预加载策略。

  2. 构建字幕源信息:创建一个 TTVideoEngineSubDecInfoModel 实例,用于承载字幕的详细信息,如 URL、格式、语言等。

    - (TTVideoEngineSubDecInfoModel *)getSubtitleInfoModel {
        // 中文字幕
        NSDictionary *subtitle1Dictionary = @{ @"format"      : @"webvtt",      // 字幕格式
                                               @"sub_id"  : @(429984091),   // 字幕 ID
                                               @"language_id"  : @(1),           // 字幕语言 ID
                                               @"language"    : @"cmn-Hans-CN", // 字幕语言
                                               @"url" : @"https://example.com/1.vtt" // 字幕下载地址
                                            };
        // 英文字幕
        NSDictionary *subtitle2Dictionary = @{ @"format"      : @"webvtt",      // 字幕格式
                                               @"sub_id"  : @(429984092),   // 字幕 ID
                                               @"language_id"  : @(2),           // 字幕语言 ID
                                               @"language"    : @"eng-US",      // 字幕语言
                                               @"url" : @"https://example.com/2.vtt" // 字幕下载地址
                                            };
        // 构建所有字幕的列表
        NSArray *subtitleArray = @[subtitle1Dictionary, subtitle2Dictionary];
        
        // 获得最终字幕数据结构,不要改变 “list” 字段名称
        NSDictionary *subtitlesDictionary = @{ @"list": subtitleArray };
        
        // 创建字幕 subModel
        TTVideoEngineSubDecInfoModel *subtitleInfoModel = [[TTVideoEngineSubDecInfoModel alloc] initWithDictionary:subtitlesDictionary];
        
        return subtitleInfoModel;
    }
    
  3. 构建并配置播放源:创建 TTVideoEngineUrlSource 时,关联上一步创建的字幕信息模型,并指定要预加载的字幕 ID。

    /// 播放 url 地址
    NSString *url = @"play url";  
    /// 本地缓存 cache key,确保跟视频一一对应且不变,这样重复播放的时候才会命中缓存
    // 可以使用 url 不变部分的 md5 值,因为 url 里可能会带有时间戳等可变字段,需要处理下
    NSString *cacheKey = url.md5String;
    
    TTVideoEngineUrlSource *source = [[TTVideoEngineUrlSource alloc] initWithUrl:url cacheKey:cacheKey];
    // 指定预加载字幕 ID
    source.subtitleId = 429984092;
    // 指定预加载字幕源字段
    source.subtitleInfoModel = [self getSubtitleInfoModel];
    

Vid 模式

构造用于预加载的 Vid 播放源时,除了视频的 vidplayAuthToken,还需提供字幕鉴权 token。

TTVideoEngineVidSource *vidSource = (TTVideoEngineVidSource *)source;
vidSource.vid = @"video id"; // 视频id
vidSource.playAuthToken = @"play token"; // 播放的 token
vidSource.subtitleAuthToken = @"subtitle token"; // 字幕的 token
vidSource.preloadSubtitleModelBlock = ^id<TTVideoEngineSubProtocol> _Nonnull(NSArray<id<TTVideoEngineSubProtocol>> * _Nonnull subModels) {
    if (subModels && subModels.count > 0) {
        // 选择要预加载的字幕,例如这里处理为预加载第一个字幕
        // 此处请根据业务逻辑(如字幕语言)匹配要预加载的字幕
        return [subModels firstObject];
    }
    return nil;
};

播放阶段

  1. 使用字幕预加载必须要开启数据加载模块 MDL 来加载外挂字幕。

    // 使用数据加载模块 MDL 加载外挂字幕,提升加载成功率
    // 0: 不使用 MDL 加载外挂字幕;1: 使用 MDL 加载外挂字幕
    [self.videoEngine setOptionForKey:VEKKeySubTitleEnableMDL_BOOL value:@(1)];
    
  2. 指定播放的字幕 ID。将占位符 <#SubtitleID#> 替换为预加载播放源中 source.subtitleId 指定的字幕 ID。

    [self.videoEngine setOptionForKey:VEKeyPlayerSwitchSubtitleId_NSInteger value:@(<#SubtitleID#>)];
    
  3. 监听命中回调 :通过实现 TTVideoEngineDelegatevideoEngine:subtitleKey:subtitleHitCacheSize: 方法,根据 cacheSize 是否大于 0 来判断本次播放是否成功命中了预加载的字幕缓存。

    /**
     * @locale zh
     * @type callback
     * @brief 字幕预加载命中回调。
     * @param videoEngine `videoEngine` 对象。
     * @param key 字幕缓存的唯一标识符。
     * @param cacheSize 命中缓存大小。
     * @notes 如果您使用字幕预加载功能,通过 `cacheSize` 是否大于 0 可以判断当此播放是否命中字幕预加载。
     */
    - (void)videoEngine:(TTVideoEngine *)videoEngine subtitleKey:(NSString *)key subtitleHitCacheSize:(NSInteger)cacheSize {
        
    }
    

播放过程中动态添加字幕源

在播放过程中,可以通过 addNewSubtitleModelswitchNewSubtitleModel 方法动态地添加新的字幕源并按需切换。

说明

动态添加字幕源自 1.47.1.10 起支持。

仅添加字幕源

// 初始化JSON字幕信息
// sub_id:(必填)字幕 ID,用于切换不同字幕;业务需要确保 sub_id 是唯一的。
// language:(必填)字幕语言,字幕语言和字幕ID对照表参考链接
// language_id:(必填)语言 ID,字幕语言和字幕ID对照表参考链接
// url:(必填)字幕文件 URL
// format:(必填)字幕格式,支持 webvtt 和 srt
NSDictionary *subModelDic = @{ @"sub_id": @(1),
                                       @"language": @"cmn-Hans-CN",
                                       @"language_id": @(1),
                                       @"url": @"https://example.srt",
                                       @"format": @"srt"
                                     };
// 构建字幕源Model
TTVideoEngineSubModel *subModel = [[TTVideoEngineSubModel alloc] initWithDictionary:subModelDic];
// 播放过程中添加字幕,不会切换到新添加的字幕,需要手动切换新添加的字幕
[self.videoEngine addNewSubtitleModel:subModel];

添加字幕源并直接展示

// 初始化JSON字幕信息
// sub_id:(必填)字幕 ID,用于切换不同字幕
// language:(必填)字幕语言,字幕语言和字幕ID对照表参考链接
// language_id:(必填)语言 ID,字幕语言和字幕ID对照表参考链接
// url:(必填)字幕文件 URL
// format:(必填)字幕格式,支持 webvtt 和 srt
NSDictionary *subModelDic = @{ @"sub_id": @(1),
                                       @"language": @"cmn-Hans-CN",
                                       @"language_id": @(1),
                                       @"url": @"https://example.srt",
                                       @"format": @"srt"
                                     };
// 构建字幕源 Model
TTVideoEngineSubModel *subModel = [[TTVideoEngineSubModel alloc] initWithDictionary:subModelDic];
// 播放过程中添加字幕,会自动切换到新添的字幕
// 会触发 videoEngine:onSubSwitchCompleted:currentLangId: 回调
[self.videoEngine switchNewSubtitleModel:subModel];

参考信息

JSON 字幕信息说明

JSON 字幕信息包含以下字段:

字段

说明

sub_id

(必填)字幕 ID,用于在播放器中区分不同的字幕。

  • 如果您从视频点播服务获取字幕,可使用视频点播服务下发的字幕数据中的 SubtitleId 字段。
  • 如果您是自行拼装字幕 JSON,可以使用 Index 标识来区分字幕。

language_id

(必填)语言 ID。取值详见语言。您需要自行维护字幕 ID 与语言 ID 的映射关系。

language

(必填)语言。取值详见语言

url

(必填)字幕文件 URL。

format

(必填)字幕格式,支持 webvttsrt

示例如下:

{
  "list": [
    {
      "language": "rus-RU",
      "language_id": 6,
      "url": "https://example.volcengine.com/cbebedaade0947ce51a*******17f0b13/6087d12f/video/tos/cn/tos-cn-o-0004/52ce3882d70941d5b660913cbd83d969/",
      "format": "webvtt",
      "sub_id": 328934091
    },
    {
      "language": "cmn-Hans-CN",
      "language_id": 1,
      "url": "https://example.volcengine.com/93adb942***bdfce8cb/6087d12f/video/tos/***a4122dac42d69e8233a4dfda82fe/",
      "format": "webvtt",
      "sub_id": 429984091
    },
    {
      "language": "cmn-Hans-CN|eng-US",
      "language_id": 5,
      "url": "https://***.com/d782d36702***7b9719/6087d12f/video/tos/***5f0d106146a19ad566b967211091/",
      "format": "webvtt",
      "sub_id": 829987091
    }
  ]
}