点播 SDK 支持在拖拽进度条或执行 Seek 操作时,通过查看视频缩略图快速预览指定进度的视频内容。进度条缩略图预览功能基于视频雪碧图实现。雪碧图是由多帧截图拼接而成的一张大图,具有以下好处:
以下为一张雪碧图示例。该雪碧图中共包含 13 张缩略图。
基于上述雪碧图的进度条缩略图预览效果如下:
PlayAuthToken
时签入 needThumbs=1
,详见以下服务端 SDK 文档:
通过 onFetchedVideoInfo 回调获取雪碧图信息 VideoThumbInfo
。示例代码如下:
public boolean onFetchedVideoInfo(VideoModel model) { final List<VideoThumbInfo> thumbInfoList = videoModel.getThumbInfoList(); if (thumbInfoList != null && thumbInfoList.size() > 0) { // 使用 index 为 0 的 VideoThumbInfo 即可。 VideoThumbInfo info = thumbInfoList.get(0); } }
以下为 VideoThumbInfo
示例。详细参数说明请见 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" }]
参考以下示例代码获取雪碧图参数的值:
// 缩略小图总个数。 int imgNum = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_CAPTURE_NUM) // 雪碧大图中每行包含的缩略小图数量。 int xLength = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_IMG_X_LEN); // 雪碧大图中每列包含的缩略小图数量。 int yLength = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_IMG_Y_LEN); // 每张缩略小图的宽,单位为 pixel。 int xSize = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_CELL_WIDTH); // 每张缩略小图的高,单位为 pixel。 int ySize = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_CELL_HEIGHT); // 雪碧大图格式。 int format = info.getValueStr(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_FORMAT); // 雪碧大图 URL 列表。 List<String> urls = info.getUrls(); // 相邻缩略小图的时间间隔,单位为秒。 double interval = info.getValueDouble(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_INTERVAL);
参考以下示例代码获取并展示指定播放位置的缩略图:
// 1. 根据播放位置 postion 和雪碧图 Interval 计算出缩略小图在雪碧大图中的 index。 final int currentThumbIndex = getCurrentThumbIndex(mVideoThumbInfo, position); // 2. 根据缩略小图的 index 和每张雪碧大图包含缩略小图的个数,计算出待展示的缩略小图在哪张雪碧大图中。 final int currentSpriteIndex = getSpriteIndex(mVideoThumbInfo, currentThumbIndex); // 3. 下载对应的雪碧大图并缓存到磁盘。 downloadThumbs(mVideoThumbInfo, currentSpriteIndex); // 4. 获取播放位置 postion 对应的缩略小图。 Bitmap bitmap = getThumbBitmap(context, mVideoThumbInfo, currentThumbIndex); // 5. 将 bitmap 展示到对应的控件即可。 final RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(mContext.getResources(), bitmap); drawable.setAntiAlias(true); mImageView.setImageDrawable(drawable); private static void downloadThumbs(VideoThumbInfo thumbInfo, int splitIndex) { String url = thumbInfo.getUrls().get(splitIndex); // 缓存到磁盘的路径需自定义,以下仅为简单示例。 String path = context.getCacheDir().getAbsolutePath() + "/thumb/" + md5(url) + ".jpg" ; File imageFile = new File(path); if (!imageFile.exists()) { // 下载雪碧图并存入本地。 } else { // 已存在,无需重复下载。 } } private int getCurrentThumbIndex(final VideoThumbInfo currentThumbInfo, final long position) { double interval = currentThumbInfo.getValueDouble( VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_INTERVAL); return (int) (position / 1000 / interval); } private int getSpriteIndex(final VideoThumbInfo currentThumbInfo, final long thumbIndex) { final int xLength = currentThumbInfo.getValueInt( VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_IMG_X_LEN); final int yLength = currentThumbInfo.getValueInt( VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_IMG_Y_LEN); return (int) (thumbIndex / (xLength * yLength)); } public Bitmap getThumbBitmap(Context context, VideoThumbInfo info, int index) { if (context == null || info == null) { return null; } Rect rect = new Rect(); int xLength = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_IMG_X_LEN); int yLength = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_IMG_Y_LEN); int xSize = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_CELL_WIDTH); int ySize = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_CELL_HEIGHT); int imgNum = info.getValueInt(VideoThumbInfo.VALUE_VIDEO_THUMB_INFO_CAPTURE_NUM); if (index >= imgNum) { index = imgNum - 1; } int spriteIndex = index / (xLength * yLength); // 缩略小图在雪碧大图中的 index index = index % (xLength * yLength); rect.left = (index % xLength) * xSize; rect.top = (index / xLength) * ySize; rect.right = rect.left + xSize; rect.bottom = rect.top + ySize; try { // 磁盘的路径需自定义,以下仅为简单示例。 String url = info.getUrls().get(spriteIndex); String path = context.getCacheDir().getAbsolutePath() + "/thumb/" + md5(url) + ".jpg" ; BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(path, false); Bitmap decodeBitmap = decoder.decodeRegion(rect, null); decoder.recycle(); return decodeBitmap; } catch (Exception e) { Log.d(TAG, "getThumbBitmap Exception " + e); } return null; }