点播 SDK 支持在拖拽进度条或执行 Seek 操作时,通过查看视频缩略图快速预览指定进度的视频内容。进度条缩略图预览功能基于视频雪碧图实现。雪碧图是由多帧截图拼接而成的一张大图,具有以下好处:
图片体积小:将许多小图合并到一张大图中,可以减少图片文件的大小。
请求次数少:通过图片整合,减少用户对服务器的请求次数,从而提高页面打开速度。
以下为一张雪碧图示例。该雪碧图中共包含 13 张缩略图。
基于上述雪碧图的进度条缩略图预览效果如下:
阅读集成准备以及快速开始 - 初始化点播 SDK 章节,确保已经完成 SDK 的初始化。
通过视频点播媒体处理服务生成雪碧图。详细操作请见雪碧图。
点播 SDK 当前仅支持在以 Vid 方式播放视频时进行缩略图预览。您需要在服务端签发 PlayAuthToken
时签入 needThumbs=1
,详见以下服务端 SDK 文档:
通过 videoEngine:fetchedVideoModel: 回调获取雪碧图信息 TTVideoEngineThumbInfo
。示例代码如下:
- (void)videoEngine:(TTVideoEngine *)videoEngine fetchedVideoModel:(TTVideoEngineModel *)videoModel { // 获取雪碧图的信息,目前返回雪碧图为一个数组,这里取数组第一个值即可 TTVideoEngineThumbInfo *firstThumbInfo = videoModel.videoInfo.bigThumbs.firstObject; self.thumbInfo = firstThumbInfo; }
以下为 TTVideoEngineThumbInfo
示例。详细参数说明请见 ThumbInfoList。
// 本示例中视频时长 270 秒。Interval 为 10,表示每 10 秒截取一张缩略小图,一共截取 27 张,由 CaptureNum 表示。 // 每张雪碧大图包含 5*5 = 25 张缩略小图,所以需要 2 张雪碧大图。 // 两张雪碧大图的 URL 可从 StoreUrls 参数中获取。 [{ "CaptureNum": 27, "StoreUrls": ["http://vod-demo-cover.volccdn.com/tos-cn-v-c91ba9/622ceb0b7f5b41afadf0fd9eb7572971_1639039860~tplv-vod-noop.image", "http://vod-demo-cover.volccdn.com/tos-cn-v-c91ba9/26d92b1fdbc74599a713b1c3c2bc3824_1639039860~tplv-vod-noop.image"], "CellWidth": 242, "CellHeight": 136, "ImgXLen": 5, "ImgYLen": 5, "Interval": 10, "Format": "jpg" }]
参考以下示例代码获取雪碧图参数的值:
对于 1.41.2 及以上版本,可直接通过 TTVideoEngineModel property
获取:
@interface TTVideoEngineThumbInfo : NSObject<NSSecureCoding> // 缩略小图总个数。 @property (nonatomic, assign) NSInteger imageNum; // 每张缩略小图的宽,单位为 pixel。 @property (nonatomic, assign) NSInteger imageXSize; // 每张缩略小图的高,单位为 pixel。 @property (nonatomic, assign) NSInteger imageYSize; // 雪碧大图中每行包含的缩略小图数量。 @property (nonatomic, assign) NSInteger imageXLen; // 雪碧大图中每列包含的缩略小图数量。 @property (nonatomic, assign) NSInteger imageYLen; // 相邻缩略小图的时间间隔,单位为秒。 @property (nonatomic, assign) CGFloat interval; // 雪碧大图格式。 @property (nonatomic, nullable, copy) NSString *fext; // 雪碧大图 URL 列表。 @property (nonatomic, nullable, copy) NSArray<NSString *> *imageURLs; /** 获取 int key value @param key with key */ - (NSInteger)getValueInt:(NSInteger)key; /** 获取 float key value @param key with key */ - (CGFloat)getValueFloat:(NSInteger)key; /** 获取 string key value @param key with key */ - (nullable NSString *)getValueStr:(NSInteger)key; /** 获取 array key value @param key with key */ - (nullable NSMutableArray<NSString *> *)getValueArray:(NSInteger)key; @end
对于 1.41.2 之前的版本,需通过 key - value 方式获取:
- (void)_parseThumbInfo:(TTVideoEngineThumbInfo *)thumbInfo { // 缩略小图总个数。 NSInteger imageNum = [thumbInfo getValueInt:VALUE_THUMB_IMG_NUM]; // 雪碧大图中每行包含的缩略小图数量。 NSInteger imageXLen = [thumbInfo getValueInt:VALUE_THUMB_IMG_X_LEN]; // 雪碧大图中每列包含的缩略小图数量。 NSInteger imageYLen = [thumbInfo getValueInt:VALUE_THUMB_IMG_Y_LEN]; // 每张缩略小图的宽,单位为 pixel。 NSInteger imageXSize = [thumbInfo getValueInt:VALUE_THUMB_IMG_X_SIZE]; // 每张缩略小图的高,单位为 pixel。 NSInteger imageYSize = [thumbInfo getValueInt:VALUE_THUMB_IMG_Y_SIZE]; // 相邻缩略小图的时间间隔,单位为秒。 CGFloat interval = [thumbInfo getValueFloat:VALUE_THUMB_INTERVAL]; // 雪碧大图格式。 NSString *format = [thumbInfo getValueArray:VALUE_THUMB_FEXT]; // 雪碧大图 URL 列表。 NSArray *imageURLs = [thumbInfo getValueArray:VALUE_THUMB_IMG_URLS]; }
参考以下示例代码获取并展示指定播放位置的缩略图:
/** * 根据播放进度获取当前需要展示的雪碧图 * @param progress 播放进度,取值范围为 [0, 1]。 */ - (UIImage * _Nullable)_updateImageWithProgress:(CGFloat)progress { NSInteger imageNum = self.thumbInfo.imageNum; NSInteger imageXLen = self.thumbInfo.imageXLen; NSInteger imageYLen = self.thumbInfo.imageYLen; if (imageNum <= 0 || imageXLen <= 0 || imageYLen <= 0) { return nil; } NSInteger imageXSize = self.thumbInfo.imageXSize; NSInteger imageYSize = self.thumbInfo.imageYSize; NSArray *imageURLs = self.thumbInfo.imageURLs; /// 雪碧图可能是多张,以下为查找当前雪碧图 Index 的代码示例,业务方可根据需要设计更优的实现 NSInteger index = MAX(0, ceil((imageNum - 1) * progress)); NSInteger urlIndex = index / (imageXLen * imageYLen); /// 以下为加载雪碧图的逻辑 /// 1. 获取当前雪碧大图的下载地址 NSString *urlString = nil; if (urlIndex < imageURLs.count) { urlString = imageURLs[urlIndex]; } if (!urlString.length) { return nil; } /// 2. 下载雪碧大图。以下代码仅为展示,这里需要根据业务设计不同的多线程提高效率 /// 例如在播放开始前就开始记载雪碧图缓存本地,seek 是减少雪碧图加载时间 ThumbnailHelper *thumbnailHelper = [ThumbnailHelper shared]; UIImage *thumbBigImage = [thumbnailHelper getImageWithUrl:urlString]; /// 3. 从雪碧大图中截取当前需要展示的缩略小图。以下代码仅为展示,业务方可根据需要设计更优的实现 if (thumbBigImage) { CGFloat x = (index % imageXLen) * imageXSize; CGFloat y = (index / imageXLen % imageYLen) * imageYSize; CGRect rect = CGRectMake(x, y, imageXSize, imageYSize); UIImage *thumbImge = [self getThumbImgFromBigImage:thumbBigImage rect:rect]; return thumbImge; } return nil; } /** * 从雪碧大图中裁剪缩略小图 * * @param bigImage 雪碧大图 * @param rect 裁剪的 rect */ - (UIImage *)getThumbImgFromBigImage:(UIImage *)bigImage rect:(CGRect)rect { CGImageRef subImageRef = CGImageCreateWithImageInRect(bigImage.CGImage, rect); CGRect smallBounds = CGRectMake(0, 0, CGImageGetWidth(subImageRef), CGImageGetHeight(subImageRef)); UIGraphicsBeginImageContext(smallBounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextDrawImage(context, smallBounds, subImageRef); UIImage *img = [UIImage imageWithCGImage:subImageRef]; CGImageRelease(subImageRef); UIGraphicsEndImageContext(); return img; }