前言
项目中有时候需要获取视频封面(缩略图,类似于图片列表),并展示给用户观看。
下面是整理一下自己测试用的。
总结
目前我知道的就有如下两种方式,但对我来说不是太理想,不知道是否还有其他的更有效的方式获取视频封面,如果有知道的请留言,谢谢。
- 使用ThumbnailUtils的createVideoThumbnail 这种方式获取存在一定的缺陷,因为很多前面都是黑色的。
- 使用MediaMetadataRetriever可以指定某个时间点获取对应的图像帧,这个可以减少获取不到概率。
正文
使用ThumbnailUtils
/** * 获取视频第一帧 * * @param path * @return */ public Bitmap getVideoThumbnail(String path) { if (TextUtils.isEmpty(path)) { return null; } Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MINI_KIND); return bitmap; }
除了Thumbnails.MINI_KIND,还有Thumbnails.FULL_SCREEN_KIND 和Thumbnails.MICRO_KIND。
- MINI_KIND 宽是512,但高没有固定的缩略图
- FULL_SCREEN_KIND 完整大小的图片
- MICRO_KIND 96 *96的缩略图
由于现实的高宽可以固定,同时我们不需要512或者固定高宽,因此需要做一定的转换。
//对获取的图进行一定的转换 if (null != bitmap) { bitmap = ThumbnailUtils.extractThumbnail(bitmap, DEFAULT_WIDTH_125, DEFAULT_HEIGHT_100, ThumbnailUtils.OPTIONS_RECYCLE_INPUT); }
小结一下:
这种方大多数图片是可以解析出来的,但总有一部分无法提取封面,导致用户不满意。
使用MediaMetadataRetriever
由于通过上面方式,不能有效获取封面(反正客户不接受),因此改为使用getFrameAtTime()通过指定时间获取对应的一帧。
getFrameAtTime()方法具体参数如下:
public Bitmap getFrameAtTime(long timeUs, int option)
- 第一个参数 :
是传入截取时间,只能是us(微秒)
- 第二个参数
OPTION_CLOSEST
在给定的时间,检索最近一个帧,这个帧不一定是关键帧。
OPTION_CLOSEST_SYNC
在给定的时间,检索最近一个同步与数据源相关联的的帧(关键帧)。
OPTION_NEXT_SYNC
在给定时间之后检索一个同步与数据源相关联的关键帧。
OPTION_PREVIOUS_SYNC
在给定时间之前检索一个同步与数据源相关的关键帧
这里为了提取我们想要的帧,不使用关键帧,所以用 OPTION_CLOSEST
/** * 获取缩略图,从第四秒获取,可以获取大多数的帧 * 缺点:低效率和耗时 * @param path * @return */ public Bitmap getVideoThumbnail2(String path) { if (TextUtils.isEmpty(path)) { return null; } MediaMetadataRetriever mMediaMetadataRetriever = new MediaMetadataRetriever(); try { if (null != mMediaMetadataRetriever) { Bitmap thumbTempBitmap = null; mMediaMetadataRetriever.setDataSource(path); //跳过前面7秒,这种做法是规律大部分视频前面几秒没有图像的帧,但缺点就是效率低和耗时 for (int i = 8; i < 10; i++) { thumbTempBitmap = mMediaMetadataRetriever.getFrameAtTime(i * 1000 * 1000, MediaMetadataRetriever.OPTION_CLOSEST); if (null != thumbTempBitmap) { break; } } if (null != thumbTempBitmap) { return thumbTempBitmap; } } } catch (Exception e) { e.printStackTrace(); } finally { if (null != mMediaMetadataRetriever) { mMediaMetadataRetriever.release(); } } return null; }
小结一下
使用这种方式,可以满足客户,但缺点也比较明显:效率低和耗时。
参考文章
历史上的今天
暂无评论...
随机推荐
[摘]Android 系统重启原因分析
重启原因分类1.上层造成重启system_server被杀watchdog重启重要线程阻塞2.kernel造成重启空指针非法地址3.kernel watchdog造成重启,原因不确定内存原因nand驱动log查看步骤及关键字1. 重启后的kernel.log或...
Android存储单位转换
G M K B 单位之间转换,直接上代码 // storage, G M K B public static String convertStorage(long size) { long kb = 1024; long mb = kb <...
[代码片段]MediaCode 播放Video中的音频
前言这就只做使用MediaCodec+AudioTrack播放Video中的音频正文原理通过MediaExtractor获取媒体的编码信息[Track索引,MediaMime,MediaFormat]根据编码信息进行创建MediaCodec在子线程循环dequeueInputBuff...
MediaPlayer java层介绍
前言Android中经常用MediaPlayer控制音频/视频文件和流的播放。虽然经常用,但没怎么看其源码,今天有空记录一下,方便自己查阅。正文本篇涉及的源码目录frameworks\base\media\java\android\media\MediaPlayer.javaPS:只是...
windows下FFmpeg使用以及ffmpeg抽取视频的关键帧
FFmpeg 简介FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中编译。这个项目是由 Fabrice ...
Android includeFontPadding属性的介绍
前言Android开发中,我们知道TextView显示文本时是存在留白的,如图一的第一行[读书导航],明显比第二行“高大威猛”些。虽然TextView默认存在留白,正常情况下的影响可以忽略不计,但如果换了个别字体后,如图二的第一行[读书导航],加上字体设计也存在留白,导致TextView占用的位...