目录

前言:

1.使用Glide获取视频某一帧:

1.1打断点可以看到bitmap图片信息如下:

1.2 glide输出图片宽高:

1.3 输出的日志如下:

2.使用MediaMetadataRetriever方式获取视频某一帧:

2.1 断点截图如下:

2.2 日志打印如下:

3.使用TextureView方式获取视频某一帧:

3.1 调试输出图片bitmap信息:

3.2 日志打印图片宽高为:

4.遇到的问题如下:

4.1 使用glide和MediaMetadataRetriever方式时由于时间是微妙所以需要换算成毫秒*1000

4.2 使用glide方式会有延迟获取到的封面优肯不准确

4.3 使用MediaMetadataRetriever方式会出现卡顿现象,由于是网络在线查询,所以网络不好时查询很慢,一般会用rxjava异步去查询,列表不建议用这个。

5.从上面5-1、5-2、5-3的截图可以看出封面是实时显示的,很符合需求视频暂停到那一秒就显示当前某一帧的封面,而且不会出现卡顿.

6.工具类源码如下:

7.总结:以上就是今天的内容,使用三种方式实现获取视频的某一帧,最后选择的是第三种,大家可以根据需要自行选择,如果小伙伴们有更好的方法欢迎留言,后面有时间会整理出来一个列表播放暂停进入详情页再次返回的demo,谢谢大家!


​​​​​​​

前言:

在Android开发中获取视频的某一帧很常见,相信大家都用过腾讯视频、爱奇艺、优酷等,里面会有直播或者播放视频时暂停时显示当前一帧的封面,或者视频暂停时从视频列表进入详情然后再返回时显示之前暂停的界面。今天先说下三种方式实现获取视频某一帧显示封面,然后说遇到的问题.

1.使用Glide获取视频某一帧:

/**
 * 使用Glide方式获取视频某一帧
 * @param context 上下文
 * @param uri 视频地址
 * @param imageView 设置image
 * @param frameTimeMicros 获取某一时间帧.
 */
public static void loadVideoScreenshot(final Context context, String uri, ImageView imageView, long frameTimeMicros) {
    RequestOptions requestOptions = RequestOptions.frameOf(frameTimeMicros);
    requestOptions.set(FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST);
    requestOptions.transform(new BitmapTransformation() {
        @Override
        protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
            Log.d("--使用glide方式--", "高度为" + toTransform.getHeight() + "寛度为" + toTransform.getWidth());
            return toTransform;
        }
        @Override
        public void updateDiskCacheKey(MessageDigest messageDigest) {
            try {
                messageDigest.update((context.getPackageName() + "RotateTransform").getBytes("utf-8"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    Glide.with(context).load(uri).apply(requestOptions).into(imageView);
}

1.1打断点可以看到bitmap图片信息如下:

img

1.2 glide输出图片宽高:

img

1.3 输出的日志如下:

img

2.使用MediaMetadataRetriever方式获取视频某一帧:

/**
 * 使用MediaMetadataRetriever获取视频指定微秒处的帧图片
 * url  网络url
 *timeUs 微秒 
 */
@SuppressLint("LongLogTag")
public static Bitmap GetFramePictures(String url, long timeUs){
    Bitmap videoShortCut = null;
    String width;
    String height;
    MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
    try {
        if (url != null) {
            HashMap<String, String> headers;
            headers = new HashMap<>();
            headers.put("User-Agent", "Mozilla/5.0 (Linux; U; Android 4.4.2; zh-CN; MW-KW-001 Build/JRO03C) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/1.0.0.001 U4/0.8.0 Mobile Safari/533.1");
            mediaMetadataRetriever.setDataSource(url, headers);
        } else {
            //mmr.setDataSource(mFD, mOffset, mLength);
        }
        videoShortCut = mediaMetadataRetriever.getFrameAtTime(timeUs, MediaMetadataRetriever.OPTION_CLOSEST);
        width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
        height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
        Log.d("--使用MediaMetadata方式--","图片高度为:" + width + "图片宽度为:" + height);
​
    } catch (IllegalArgumentException e) {
        Log.e("setFrameAtTimeWithView ERROR:" , e.toString(), e);
    }
    mediaMetadataRetriever.release();
    return  videoShortCut;
}

2.1 断点截图如下:

img

图2-1

img

图2-2

2.2 日志打印如下:

img

3.使用TextureView方式获取视频某一帧:

public Bitmap getFrontCoverBitmap() {
    Bitmap bitmap = null;
    if (textureView != null) {
        bitmap = textureView.getBitmap();
    }
    return bitmap;
}

3.1 调试输出图片bitmap信息:

img

图5-1

img

图5-2

img

图5-3

3.2 日志打印图片宽高为:

img

4.遇到的问题如下:

4.1 使用glide和MediaMetadataRetriever方式时由于时间是微妙所以需要换算成毫秒*1000

4.2 使用glide方式会有延迟获取到的封面可能不准确

4.3 使用MediaMetadataRetriever方式会出现卡顿现象,由于是网络在线查询,所以网络不好时查询很慢,一般会用rxjava异步去查询,列表不建议用这个。

5.从上面5-1、5-2、5-3的截图可以看出封面是实时显示的,很符合需求视频暂停到那一秒就显示当前某一帧的封面,而且不会出现卡顿.

6.工具类源码如下:

videotimedemo: 视频播放时间 (gitee.com)

7.总结:以上就是今天的内容,使用三种方式实现获取视频的某一帧,最后选择的是第三种,大家可以根据需要自行选择,如果小伙伴们有更好的方法欢迎留言,后面有时间会整理出来一个列表播放暂停进入详情页再次返回的demo,谢谢大家!

Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐