Android MediaMetadataRetriever和ThumbnailUtils获取视频的关键帧和非关键帧,提取视频封面


MediaMetadataRetriever (硬)

注:提取关键帧要比非关键帧快很多倍

getFrameAtTime参数
方法原型:public Bitmap getFrameAtTime(long timeUs, int option) 

第一个参数
是传入截取时间,只能是us(微秒) 


第二个参数

OPTION_CLOSEST   
在给定的时间,检索最近一个帧,这个帧不一定是关键帧。

OPTION_CLOSEST_SYNC   
在给定的时间,检索最近一个同步与数据源相关联的的帧(关键帧)。

OPTION_NEXT_SYNC  
在给定时间之后检索一个同步与数据源相关联的关键帧。

OPTION_PREVIOUS_SYNC  
在给定时间之前检索一个同步与数据源相关的关键帧

这里为了提取我们想要的帧,不使用关键帧,所以用 OPTION_CLOSEST
public Bitmap getFrameAtTime() 

//如果不加参数的话,提取第一个关键帧
public Bitmap getFrameAtTime() {
        return getFrameAtTime(-1, OPTION_CLOSEST_SYNC);
    }
    
   /**
     * 获取视频文件截图
     *
     * @param path 视频文件的路径
     * @return Bitmap 返回获取的Bitmap
     */
    public Bitmap getVideoThumb(String path) {
        MediaMetadataRetriever media = new MediaMetadataRetriever();
        media.setDataSource(path);
        Bitmap frameAtTime = media.getFrameAtTime(1 * 1000 * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
        if (frameAtTime == null) {
            frameAtTime = media.getFrameAtTime(3 * 1000 * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
        }
        return frameAtTime;
    }

ThumbnailUtils(硬)内部封装了MediaMetadataRetriever

    /**
     * 获取视频文件截图
     *
     * @param path 视频文件的路径
     * @return Bitmap 返回获取的Bitmap
     * MINI_KIND		FULL_SCREEN_KIND		 MICRO_KIND
     */
    public Bitmap getVideoCover(String path) {
        Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Images.Thumbnails.MINI_KIND);
        if (bitmap == null) {
            //提取到的视频封面为空
            showToast("没有提取到的视频封面,请换个视频尝试");
            finish();
        }
        return bitmap;
    }
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果使用`MediaMetadataRetriever`获取视频帧画面被放大,可能是因为视频的分辨率与显示的视图大小不匹配导致的。你可以尝试对获取到的视频帧进行缩放以适应目标视图。 下面是一个示例代码,展示了如何使用`MediaMetadataRetriever`获取视频帧并进行缩放: ```java import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.MediaMetadataRetriever; import android.os.Bundle; import android.widget.ImageView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = findViewById(R.id.imageView); String videoPath = "your_video_path"; // 替换成你的视频文件路径 Bitmap videoFrame = extractVideoFrame(videoPath); if (videoFrame != null) { Bitmap scaledFrame = scaleBitmap(videoFrame, imageView.getWidth(), imageView.getHeight()); imageView.setImageBitmap(scaledFrame); } } private Bitmap extractVideoFrame(String videoPath) { MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(videoPath); return retriever.getFrameAtTime(); } catch (Exception e) { e.printStackTrace(); } finally { retriever.release(); } return null; } private Bitmap scaleBitmap(Bitmap bitmap, int targetWidth, int targetHeight) { return Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, false); } } ``` 在上述代码中,`extractVideoFrame()`方法使用`MediaMetadataRetriever`获取视频的帧画面。然后,使用`scaleBitmap()`方法将视频帧画面缩放为目标视图的大小。最后,将缩放后的位图设置给`ImageView`来显示。 请注意,这段代码假设目标视图的大小已经确定。如果目标视图的大小在运行时才能确定,你可以在适当的时机调用`scaleBitmap()`方法来进行缩放。另外,如果视频的分辨率与目标视图的宽高比不匹配,可能会导致画面被拉伸或裁剪。你可以根据需求调整缩放逻辑,以保持画面的正确比例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值