预加载是指在开始播放之前,提前下载即将播放视频的头部数据,播放时达到快速起播,大幅优化播放体验;预加载在各播放场景都可以使用,接入成本低,效果明显。
预加载策略
预加载使用原则是不影响当前视频播放,选择合理精细的预加载时机,可以有效的提高预加载命中率,提升首帧体验。如果粗放不合理的预加载时机,会出现浪费流量的现象,导致成本增加。
如下介绍 3个常见场景的预加载策略的效果展示和推荐简单使用规则。
![alt](https://lf6-volc-editor.volccdn.com/obj/volcfe/sop-public/upload_bcdadf3f08504b71505606a1321b7281.png)
短视频(竖屏类抖音)
场景特点:类似抖音场景,一屏只展示一个竖版视频,一次滑动只能滑动一个视频。
说明
我们推荐您使用最佳策略,能够快速实现零首帧体验的短视频播放效果。详情请见最佳实践:iOS 短视频场景。
- 预加载时机:当前视频缓冲时长超过 20秒或全部缓冲完成,可以开始向下进行预加载。
- 预加载数量:推荐预加载视频数量设置为 3个。用户停留在当前视频位置观看视频,当前位置记为 index,向下预加载 n 个视频,预加载范围:[index + 1,index+n]。
- 预加载大小:建议预加载的大小设置 800K。
- 取消:滑动切换播放视频时,取消全部预加载,避免对当前播放视频带宽产生争抢,影响当前视频的首帧。
中视频(横屏类西瓜)
场景特点: Feed 一屏中同时存在 2个以上视频。Feed 流可以快速滑动,一次滑动可能划过多个视频。
- 预加载时机: 当前视频缓冲时长超过 20秒或全部缓冲完成,可以开始向下进行预加载。
- 预加载数量: 推荐预加载视频数量设置为 5个。用户停留在当前视频位置观看视频,当前位置记为 index,向下预加载 n 个视频,预加载范围:[index + 1, index + n]。
- 预加载大小: 建议预加载的大小设置 800K。
- 取消: 滑动切换播放视频时,取消全部预加载,避免对当前播放视频带宽产生争抢,影响当前视频的首帧。
长视频
场景特点:沉浸式的全屏播放场景和播放页播放场景,例如影视、综艺等长视频的播放场景。
可根据具体场景,例如影视综艺,可以在当前剧集将要播放完成,预加载下一剧集。
接入预加载
在开始添加任务之前,需要明确 SDK 启动配置信息是否符合预期。
注意
预加载为高级版 SDK 功能,若您目前使用的是基础版 SDK,请先在控制台中购买高级版 License,在高级版 SDK中进行接入。
接入方式
接入预加载的方式有 2 种:DirectUrl 模式和 Vid 模式。
预加载与播放使用相同的播放源结构。为保证播放能命中预加载缓存,需确保预加载与播放构造的播放源 vid、url、cacheKey 一致。代码示例如下所示。
#import <TTSDK/TTVideoEngineHeader.h>
-(TTVideoEngineUrlSource *)createUrlSource {
NSString *vid = @"video id"; // 由业务指定的视频源唯一ID。是一组内容相同但分辨率、编解码格式、封装格式等不同的视频集合的ID。
NSString *url = @"http://www.example.com/h264.mp4";
// cacheKey 用作磁盘缓存的文件名,建议采用 url 中能标识视频文件的部分的 MD5 值
NSString *cacheKey = [url md5String];
// 如果需要指定 URL source 的 encodetype 和解密 key 或标明是否为 HDR 播放源可以使用其他重载的接口. 见: TTVideoEngineUrlSource.h
TTVideoEngineUrlSource *source = [[TTVideoEngineUrlSource alloc] initWithUrl:url cacheKey:cacheKey videoId:vid];
return source;
}
代码示例如下所示。
- (void)addPreloadTask {
// preloadSize: 预加载大小,例如 800k
TTVideoEnginePreloaderURLItem * urlItem = [TTVideoEnginePreloaderURLItem urlItemWithVideoSource:[self createUrlSource] preloadSize:800 * 1024];
urlItem.preloadProgress = ^(TTVideoEngineLoadProgress * _Nonnull progress) {
// preload progress
};
urlItem.preloadEnd = ^(TTVideoEngineLocalServerTaskInfo * _Nullable info, NSError * _Nullable error) {
// preload end
};
[TTVideoEngine ls_addTaskWithURLItem:urlItem];
}
取消预加载任务说明
取消任务,对没开始执行的任务和正在下载的任务有影响,对已经完成的任务没有影响。
代码示例如下所示。
// 取消单个预加载任务
// cacheKey 为添加任务时对应的 key.
[TTVideoEngine ls_cancelTaskByKey:cacheKey];
// 取消全部预加载任务
[TTVideoEngine ls_cancelAllTasks];
构造播放源预加载与播放使用相同的播放源结构。为保证播放能命中预加载缓存,需确保预加载与播放构造的播放源 vid、playAuthToken、encodeType、resolution 一致。
说明
预加载和播放使用相同的播放源结构,需要确保一些参数的一致性。例如:
分辨率resolution
需要保证预加载和播放中的分辨率一致。当业务未指定分辨率时, SDK 内部在预加载和播放时,将使用TTVideoEngineResolutionTypeSD
作为默认值。编码类型encodeType
也是需要保证预加载和播放中的取值一致。当业务未指定编码类型时,SDK 内部在预加载和播放时,将使用TTVideoEngineH264
作为默认值。代码示例如下所示。
#import <TTSDK/TTVideoEngineHeader.h>
- (TTVideoEngineVidSource *)createVidSource {
NSString *vid = @"your video id"; // appServer 下发
NSString *playAuthToken = @"your video id's play auth token"; // appServer 下发
TTVideoEngineEncodeType encodeType = TTVideoEngineH264;
// TTVideoEngineEncodeType encodeType = TTVideoEngineh265;
TTVideoEngineResolutionType resolution = TTVideoEngineResolutionTypeSD;
TTVideoEngineVidSource *vidSource = [[TTVideoEngineVidSource alloc] initWithVid:vid playAuthToken:playAuthToken resolution:resolution encodeType:encodeType isDash:NO isHLS:NO];
return vidSource;
}
添加预加载任务代码示例如下所示。
- (void)addPreloadTask1 {
TTVideoEnginePreloaderVidItem *item = [TTVideoEnginePreloaderVidItem vidItemWithVideoSource:[self createVidSource] preloadSize:GLOBAL_CONFIG.cacheSize ?: (800 * 1024)];
item.fetchDataEnd = ^(TTVideoEngineModel * _Nullable model, NSError * _Nullable error) {
// get video model end
};
item.preloadProgress = ^(TTVideoEngineLoadProgress * _Nonnull progress) {
// preload progress
};
item.preloadEnd = ^(TTVideoEngineLocalServerTaskInfo * _Nullable info, NSError * _Nullable error) {
// preload end
};
[TTVideoEngine ls_addTaskWithVidItem:item];
}
播放时通过
configResolution:
接口设置预期分辨率,确保播放和预加载设置分辨率信息一致,代码示例如下所示。
// 和上面预加载的分辨率一致
[engine configResolution:TTVideoEngineResolutionTypeSD];
说明
取消任务,对没开始执行的任务和正在下载的任务有影响,对已经完成的任务没有影响。
// 取消单个预加载任务
[TTVideoEngine ls_cancelTaskByVideoId:vid];
// 取消全部预加载任务
[TTVideoEngine ls_cancelAllTasks];
验证是否命中预加载
通过播放器的 delegate 回调查看是否命中预加载。Engine 实例的代理方法的代码示例如下所示。
// engine 实例的代理方法
- (void)videoEngine:(TTVideoEngine *)videoEngine mdlKey:(NSString *)key hitCacheSze:(NSInteger)cacheSize {
// cacheSize > 0 , 表示命中缓存信息
// cacheSize = 0 , 未命中缓存,请排查预加载任务是否成功,如果是vid方式,请检查播放和预加载的reslution是否一致
}
说明
- 播放器默认支持边下载边播放。
- 如果某个视频是第一次播放,命中的缓存是预加载下载的数据。
- 第二次播放,可能是第一次播放的缓存。
- 如果测试预加载缓存的命中率,前提要保证每个视频都是第一次播放,建议首次安装进行测试。
设置预加载任务并发数
// 设置预加载任务的并发数,默认值为 2
// 如下设置为 1,串行执行预加载任务
[TTVideoEngine ls_localServerConfigure].preloadParallelNum = 1;