本文介绍如何实现播放源过期自动刷新功能。当视频的 CDN 播放地址(URL)因安全策略(如签名验证)而具有时效性时,此功能可以在 URL 过期后自动获取新的有效地址,从而保证视频的持续流畅播放,避免因地址失效导致的播放中断。
说明
如需实现此功能,请集成 iOS 播放器 SDK 1.42.2.6 或以上版本。
在为客户端实现播放源过期自动刷新功能前,您需要确保完成以下操作:
GET /api/refreshUrl
expiredUrl
(已过期的 URL){ "url": "https://www.example.com/1.mp4", // 刷新后的地址 "expireInMS": 1705392219000 // 新地址的过期时间戳(毫秒) }
创建一个类并实现 TTVideoURLRefreshFetcher
协议。在该协议的 refreshNewUrls:oldUrl:complateBlock:errorBlock:cancelBlock:
方法中,请求您的应用服务端提供的刷新 URL 接口。
@interface CustomRefreshFetcher () @property (nonatomic, assign) BOOL isLoading; @end @implementation CustomRefreshFetcher #pragma mark - TTVideoURLRefreshFetcher - (void)refreshNewUrls:(NSString * _Nonnull)cacheKey oldUrl:(NSString * _Nonnull)oldUrl complateBlock:(TTVideoURLRefreshCompleteBlock)complateBlock errorBlock:(TTVideoURLRefreshErrorBlock)errorBlock cancelBlock:(TTVideoURLRefreshCancelBlock)cancelBlock // 该回调会被多次出发,这里做一个兼容处理 if (self.isLoading) { return; } self.isLoading = YES; // 这里为请求新的 URL 示例代码,业务需要根据自身业务替换这部分逻辑 [self.networkClient fech:oldUrl success: ^(id response) { // 地址刷新成功 NSString *newUrl = [response newUrl]; // 注意单位是毫秒 NSString *expireTimeInMs = [response expireTime]; !complateBlock ?: complateBlock(newUrl, expireTimeInMs); self.isLoading = NO; } failure: ^(NSError *error) { // 地址刷新失 !errorBlock ?: errorBlock(error); self.isLoading = NO; } cancel: ^() { // 用户取消请求,比如退出播放页. 调用 cancelBlock,SDK 内部释放资源 !cancelBlock ?: cancelBlock(); self.isLoading = NO; }]; } // 播放器 SDK 请求取消刷新 - (void)cancel { // 请实现取消请求逻辑 [self.networkClient cancelRequest]; } @end
创建 TTVideoEngineUrlSource
播放源时,将其 enableFallbackRefresh
属性设置为 YES
,开启播放源过期自动刷新功能。
- (void)play { // 构建播放源 NSString *url = @"http://test.mp4"; // 播放器地址 NSString *cacheKey = @"cache key"; // 缓存 cache key,建议使用 url的 md5 值 TTVideoEngineUrlSource *source = [[TTVideoEngineUrlSource alloc] initWithUrl:url cacheKey:cacheKey]; source.enableFallbackRefresh = YES; // 开启播放源过期自动刷新功能 // 如果是 HLS 播放源,建议开启如下 option [self.videoEngine setOptionForKey:VEKKeyIsEnableSegError value:@(YES)]; // 实现播放地址刷新的 protocol, 注意 refreshFetcher 要定义成全局变量,避免使用局部变量被提前释放导致自刷新不生效 self.refreshFetcher = [[CustomRefreshFetcher alloc] init]; self.videoEngine.urlRefreshFetcher = self.refreshFetcher; // 设置播放源 [self.videoEngine setVideoEngineVideoSource:source]; // 播放 [self.videoEngine play]; }
(可选)为 HLS 播放源自定义 CacheKey:如果 HLS 视频 TS 分片的 URL 包含签名,需要通过设置 TTVideoEngine
的 HLSProxyDelegate
并实现 generateFileKey:hlsFileKey:infos:
协议方法,来自定义 TS 文件的 cacheKey 生成规则。
/* * 为 HLS 源自定义 CacheKey,非 HLS 源不用调用 CacheSettings.getInstance().setGenerateFileKeyCallback 方法。 * 针对 HLS,TS 地址的 cacheKey 生成规则是播放器内部生成的,规则是 md5(pathOf(tsUrl)); * 对于 TS 地址签算在 path 中的情况,为保证 cacheKey 的唯一性,需要业务通过下面接口自定义 TS cacheKey 的生成规则。 */ // 1. 设置 HLSProxy 协议 [TTVideoEngine setHLSProxyDelegate:self]; // 2. 实现 HLSProxy 协议,根据业务自身需求,自定义 TS 缓存 Key, 其中 url 为 TS 地址,hlsFileKey 为 M3U8 文件 key - (NSString * _Nullable)generateFileKey:(NSString *_Nonnull)url hlsFileKey:(NSString *_Nonnull)hlsFileKey infos:(NSDictionary *_Nullable)infos { }