前言:
在项目中,通常我们有获取视频的缩略图来显示的需求。这里所说的视频的缩略图,一般是视频的第一帧画面,当然也可能我们需要获取视频中指定位置的一帧画面。
我们通过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
官方定义: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线程中。