在开发中,对视频进行操作,将视频显示在界面上时,都是显示的视频的第一帧的图片。比如,在录制视频上传(上传界面)、下载视频(视频下载列表);这两个功能我的项目中都用到了,这两个需求刚好是获取视频的第一帧的图片的两种视频形式(本地视频、网络视频)。
1.MediaMetadataRetrieve
从API10开始新增的这个类,用来获取媒体文件的信息,比如视频的某一帧。
具体运用代码如下:
MediaMetadataRetriever retriever = new MediaMetadataRetriever(); //获取网络视频 retriever.setDataSource(url, new HashMap, String>()); //获取本地视频 //retriever.setDataSource(url); Bitmap bitmap = retriever.getFrameAtTime(); FileOutputStream outStream = null; outStream = new FileOutputStream(new File(mActivity.getExternalCacheDir().getAbsolutePath() + "/" + videoName + ".jpg")); bitmap.compress(Bitmap.CompressFormat.JPEG, 10, outStream); outStream.close(); retriever.release();
获取网络视频只是在setDataSource方法中,多传入了一个HashMap的参数。
下面是这个方法的源码
public void setDataSource(String uri, Map注意:, String> headers) throws IllegalArgumentException { int i = 0; String[] keys = new String[headers.size()]; String[] values = new String[headers.size()]; for (Map.Entry, String> entry: headers.entrySet()) { keys[i] = entry.getKey(); values[i] = entry.getValue(); ++i; } _setDataSource( MediaHTTPService.createHttpServiceBinderIfNecessary(uri), uri, keys, values); }
(1)、这些操作需要网络权限,读写sd卡的权限。
(2)、在获取网络视频的第一帧的缩略图时,最好不要在主线程中进行,耗时过长容易造成ANR。
(3)、compress这个方法,我传入的quality是10,将图片质量压缩到原来十分之一,因为我是在视频下载列表中需要这张缩略图,并不要求多高的质量。
2、ThumbnailUtils
从API8开始新增了android.media.ThumbnailUtils这个类
这个类有三个静态的方法。
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(url, MediaStore.Images.Thumbnails.MINI_KIND);
这个方法直接就能获取本地视频的第一帧,第一个参数是本地视频的地址,第二个是获取到的缩略图的大小。
extractThumbnail(Bitmap source, int width, int height, int options)
extractThumbnail(Bitmap source, int width, int height)
另外两个方法是对bitmap进行处理的。
这个类不能获取网络视频的缩略图。
createVideoThumbnail方法其实也是用的MediaMetadataRetriever,对它重新进行的封装。
源码如下:
public static Bitmap createVideoThumbnail(String filePath, int kind) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(filePath);
bitmap = retriever.getFrameAtTime(-1);
} catch (IllegalArgumentException ex) {
// Assume this is a corrupt video file
} catch (RuntimeException ex) {
// Assume this is a corrupt video file.
} finally {
try {
retriever.release();
} catch (RuntimeException ex) {
// Ignore failures while cleaning up.
}
}
if (bitmap == null) return null;
if (kind == Images.Thumbnails.MINI_KIND) {
// Scale down the bitmap if it's too large.
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int max = Math.max(width, height);
if (max > 512) {
float scale = 512f / max;
int w = Math.round(scale * width);
int h = Math.round(scale * height);
bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
}
} else if (kind == Images.Thumbnails.MICRO_KIND) {
bitmap = extractThumbnail(bitmap,
TARGET_SIZE_MICRO_THUMBNAIL,
TARGET_SIZE_MICRO_THUMBNAIL,
OPTIONS_RECYCLE_INPUT);
}
return bitmap;
}
参考 http://www.linuxidc.com/Linux/2014-08/104986.htm