You need to enable JavaScript to run this app.
文档中心
文档控制台
注册
视频点播

视频点播

复制全文
下载 pdf
进阶功能
添加外挂字幕
复制全文
下载 pdf
添加外挂字幕

外挂字幕指与视频文件分离的字幕文件,用户可在播放时按需导入。播放器 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
    }
  ]
}
最近更新时间:2025.11.20 15:14:05
这个页面对您有帮助吗?
有用
有用
无用
无用