Android中获取视频的缩略图

前言:
在项目中,通常我们有获取视频的缩略图来显示的需求。这里所说的视频的缩略图,一般是视频的第一帧画面,当然也可能我们需要获取视频中指定位置的一帧画面。

我们通过MediaMetadataRetriever来获取视频的缩略图。

关于MediaMetadataRetriever:
在API Level 10添加的;
位于android.media包下;
官方定义:MediaMetadataRetriever class provides a unified interface for retrieving frame and meta data from an input media file.(MediaMetadataRetriever 类提供一个统一的接口,用于从输入媒体文件中检索帧和元数据。)

下面我们来看MediaMetadataRetriever 的构造方法、常量、公共方法:
一、构造方法:
MediaMetadataRetriever 只有一个构造方法,即MediaMetadataRetriever()。
我们得到一个MediaMetadataRetriever的实例,代码如下:

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();

二、常量,我们这里挑选四个常量进行讲解。(更多内容可以在此处https://developer.android.com/reference/android/media/MediaMetadataRetriever进行查看)
1、OPTION_CLOSEST
官方定义:This option is used with getFrameAtTime(long, int) to retrieve a frame (not necessarily a key frame) associated with a data source that is located closest to or at the given time.
简单来说就是,在给定的时间,检索最近的一帧,这个帧不一定是关键帧。我们将其作为参数传入getFrameAtTime方法的第二个参数位置。
在源码中的定义如下:

public static final int OPTION_CLOSEST          = 0x03;

2、OPTION_CLOSEST_SYNC
官方定义:This option is used with getFrameAtTime(long, int) to retrieve a sync (or key) frame associated with a data source that is located closest to (in time) or at the given time.
简单来说就是,在给定的时间,检索最近一个同步与数据源相关联的帧(关键帧)。我们将其作为参数传入getFrameAtTime方法的第二个参数位置。
在源码中的定义如下:

public static final int OPTION_CLOSEST_SYNC     = 0x02;

3、OPTION_NEXT_SYNC
官方定义:This option is used with getFrameAtTime(long, int) to retrieve a sync (or key) frame associated with a data source that is located right after or at the given time.
简单来说就是,在给定的时间之后,检索最近一个同步与数据源相关联的帧(关键帧)。我们将其作为参数传入getFrameAtTime方法的第二个参数位置。
在源码中的定义如下:

public static final int OPTION_NEXT_SYNC        = 0x01;

4、OPTION_PREVIOUS_SYNC
官方定义:This option is used with getFrameAtTime(long, int) to retrieve a sync (or key) frame associated with a data source that is located right before or at the given time.
简单来说就是,在给定的时间之前,检索最近一个同步与数据源相关联的帧(关键帧)。我们将其作为参数传入getFrameAtTime方法的第二个参数位置。
在源码中的定义如下:

public static final int OPTION_PREVIOUS_SYNC    = 0x00;

三、公共方法,我们挑选四个方法进行讲解。(更多内容可以在此处https://developer.android.com/reference/android/media/MediaMetadataRetriever进行查看)
1、public void setDataSource (String path)
官方定义:Sets the data source (file pathname) to use. Call this method before the rest of the methods in this class. This method may be time-consuming.
理解:这个方法必须在其他方法之前调用;这个方法可能是耗时的;这个方法用于设置本地视频的路径。
总结:如果是要获取本地视频的缩略图,我们可以使用这个方法设置本地视频的路径,并且该方法的调用需要在其他方法(比如getFrameAtTime(long, int)方法)之前,另外,该方法的调用不应该放在UI线程中。

2、public void setDataSource(String uri, Map headers)
官方定义:Sets the data source (URI) to use. Call this method before the rest of the methods in this class. This method may be time-consuming.
理解:这个方法必须在其他方法之前调用;这个方法可能是耗时的;这个方法可以用于设置网络视频的路径。
总结:如果是要获取网络视频的缩略图,我们可以使用这个方法设置网络视频的路径,并且该方法的调用需要在其他方法(比如getFrameAtTime(long, int)方法)之前,另外,该方法的调用不应该放在UI线程中。

3、public Bitmap getFrameAtTime ()
官方定义:Call this method after setDataSource(). This method finds a representative frame at any time position if possible, and returns it as a bitmap. Call this method if one does not care about where the frame is located; otherwise, please call getFrameAtTime(long) or getFrameAtTime(long, int)
理解:如果我们只是要获取任何时间位置的一帧,那么我们可以调用这个方法。
总结:当我们对帧的时间位置没有要求的时候,我们可以调用这个方法,得到表示该帧的Bitmap对象。

4、public Bitmap getFrameAtTime (long timeUs, int option)
官方定义:Call this method after setDataSource(). This method finds a representative frame close to the given time position by considering the given option if possible, and returns it as a bitmap.
理解:根据指定时间位置以及选项设置(比如OPTION_CLOSEST_SYNC)得到一帧的Bitmap表示。
总结:当我们需要得到指定时间位置的一帧画面时,我们可以使用该方法,得到表示该帧的Bitmap对象。

下面我们来看一个例子:
获取网络视频的第一帧画面

                final MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
                new Thread() {
                    @Override
                    public void run() {
                        mediaMetadataRetriever.setDataSource(resourceUrls[0], new HashMap());
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                iv_video_thumbnail.setImageBitmap(mediaMetadataRetriever.getFrameAtTime(0, OPTION_CLOSEST_SYNC));
                            }
                        });
                    }
                }.start();

注意:setDataSource方法必须放在工作线程中,不能放在UI线程中。任何可能耗时的操作必须不能放在UI线程中。

你可能感兴趣的:(音视频)