http://blog.csdn.net/u010499721/article/details/50338623

前些天有个师弟(在做一个仿LinkInEyes行车记录仪的app)问我怎么获取视频缩略图,起初以为很简单,就找了个常用的解决方案(用户获取正常的视频文件的缩略图):

  1. 方案1:
private void initView() {
imgPic = (ImageView) findViewById(R.id.img_pic);
seekbar = (SeekBar) findViewById(R.id.seekbar);
mmr = new MediaMetadataRetriever();
mmr.setDataSource("/sdcard/3.mp4");
// 取得视频的长度(单位为毫秒)
String time = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
seekbar.setMax(Integer.parseInt(time) * 1000);
bt = (Button) findViewById(R.id.bt);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, " " + seekbar.getProgress(), 1).show(); Bitmap bitmap = mmr.getFrameAtTime(seekbar.getProgress(),
MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
// Bitmap bitmap = mmr.getFrameAtTime(seekbar.getProgress());
imgPic.setImageBitmap(bitmap);
System.out.println(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE)+ "");
System.out.println(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE)+ "");
// mmr.release();
}
});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

要求Android api>=10

  1. 方案2:

ThumbnailUtils.createVideoThumbnail(filePath, kind);方法获取

 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

该方法在2.x系统下可用,API LEVEL > 14时却只能返回null

http://my.oschina.net/kylinhuang/blog/472757?fromerr=vASTONAf

  1. 方案3

使用开源代码:MediaMetadataRetriever

private Bitmap getBitMap() {
Bitmap b = null;
// Retrieve all metadata.
List<Metadata> metadata = new ArrayList<Metadata>(); if (mUri == null) return null;
FFmpegMediaMetadataRetriever fmmr = new FFmpegMediaMetadataRetriever();
try {
fmmr.setDataSource(mUri);
for (int i = 0; i < Constants.METADATA_KEYS.length; i++) { //注意
String key = Constants.METADATA_KEYS[i];
String value = fmmr.extractMetadata(key); if (value != null) {
metadata.add(new Metadata(key, value));
Log.i(MetadataLoader.class.getName(), "Key: " + key
+ " Value: " + value);
}
}
b = fmmr.getFrameAtTime();
if (b != null) {
Bitmap b2 = fmmr.getFrameAtTime(seekbar.getProgress(),
FFmpegMediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if (b2 != null) {
b = b2;
}
} if (b != null) {
metadata.add(new Metadata("image", b));
Log.i(MetadataLoader.class.getName(), "Extracted frame");
} else {
Log.e(MetadataLoader.class.getName(), "Failed to extract frame");
}
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} finally {
fmmr.release();
}
return b;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

fmmr.setDataSource(mUri);中uri支持的文件类型 file, http, https, mms and mmsh 支持的编码格式(音频&视频): aac, acc+, avi, flac, mp2, mp3, mp4, ogg, 3gp and more! 扩展支持: 
开源地址:https://github.com/wseemann/FFmpegMediaMetadataRetriever 
備份地址:https://github.com/qq179157977/FFmpegMediaMetadataRetriever

理论上,进过测试以上三个方案,基本的可以获取网络或本地的map4,avi等视频的缩略图了。 
但是师弟说还是获取不了,因为他获取到的是一个thm文件(idr流返回),这种文件不是视频文件,是是MP4或者MPG视频文件的索引文件,用以上三种方法根本获取不到缩略图,我就觉得奇怪,想起强大的ffmpeg也可以获取缩略图,于是下载了一个命令行的ffmpeg开始尝试获取缩略图: 
先将文件放到c盘,切换到c盘(ffmpeg也在c盘),运行: 
ffmpeg -i C:\fengkai.htm -y -f image2 -t 0.001 -s 352x240 a.jpg 
运行完毕,出现了a.jpg,还真的可以获取htm文件的缩略图

但是,ffmpeg命令要在android上运行,需要将ffmpeg(Linux版)文件放到一个目录,然后用root权限给予ffmpeg执行权,才可以调用上述获取缩略图命令,原因是系统没有ffmpeg命令~

这是只能继续找到不需要权限又能通过ffmpeg获取缩略图的demo了,找了一段时间,找到一个外国人写的牛逼开源项目: 
https://github.com/WritingMinds/ffmpeg-android-java

下载测试app

运行app,输入框输入:- 
i /sdcard/test.asf -y -f image2 -t 0.001 -s 352x240 /sdcard/a.jpg 
执行完毕,sdcard生成缩略图,棒!成功了!

附录 
thm测试文件

参考: 
http://my.oschina.net/kylinhuang/blog/472757?fromerr=vASTONAf 
http://www.tuicool.com/articles/uqmUFfY 
http://helloandroid.iteye.com/blog/1753355

android 获取视频缩略图终极解决方案(ffmpeg)的更多相关文章

  1. Android大图片裁剪终极解决方案(上:原理分析)

    转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-)  http://my.oschina.net/ryanhoo/blog/86842 约几个月前,我正 ...

  2. Android -- 获取视频第一帧缩略图

    干货 从API 8开始,新增了一个类: android.media.ThumbnailUtils这个类提供了3个静态方法一个用来获取视频第一帧得到的Bitmap,2个对图片进行缩略处理. public ...

  3. java获取视频缩略图

    近期由于在做一个关于视频播放的项目,需要使用程序自动获取视频文件的缩略图,特写此文供其他人参考,有不清楚之楚可以给我留言. 1.使用工具:ffmpeg, 官网下载地址:http://ffmpeg.or ...

  4. Android 音视频深入 六 使用FFmpeg播放视频(附源码下载)

    本篇项目地址,求starhttps://github.com/979451341/Audio-and-video-learning-materials/tree/master/FFmpeg%E6%92 ...

  5. [转]android 获取视频帧

    本文转自:http://blog.csdn.net/heart_Moving/article/details/17414067 今天做Android视频文件解码,需求:从一个视频文件获取到一帧一帧的图 ...

  6. Android 音视频深入 十四 FFmpeg与OpenSL ES 播放mp3音乐,能暂停(附源码下载)

    项目地址https://github.com/979451341/FFmpegOpenslES 这次说的是FFmpeg解码mp3,数据给OpenSL ES播放,并且能够暂停. 1.创建引擎 slCre ...

  7. Android 音视频深入 十二 FFmpeg视频替换声音(附源码下载)

    项目地址,求starhttps://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpeg%E7%BB%99%E8%A7%86%E ...

  8. Android得到视频缩略图

    视频缩略图,可以通过接口类 MediaMetadataRetriever 来实现 具体可以看代码片段 public Bitmap getVideoThumbnail(String filePath) ...

  9. Android 音视频深入 十八 FFmpeg播放视频,有声音(附源码下载)

    项目地址https://github.com/979451341/AudioVideoStudyCodeTwo/tree/master/FFmpegv%E6%92%AD%E6%94%BE%E8%A7% ...

随机推荐

  1. php windows 扩展redis

    一:客户端安装redis (1)下载地址:https://github.com/dmajkic/redis/downloads 根据电脑是多少位的使用对应的文件,如我的是64bit,那么我就选择64b ...

  2. tinycore Network card configuration during exec bootlocal.sh

    question: tinycore在boot时, 运行bootlocal.sh脚本,其中有局域网通信的部分,一直跑不通,测试了一下才知道是运行bootlocal.sh的阶段,网络可能没有配置好,ip ...

  3. WPF-Binding的源

    1. 绑定到其它元素 <Grid> <StackPanel> <TextBox x:Name="textbox1" /> <Label C ...

  4. CMake error:System Error:No such file or directory CMake error:Could not open file for write in copy operation xxxx.ros_Config.cmake.tmp.

    微型电脑或嵌入式与电脑还是有点不同的,在微型电脑上ros indigo 版本下利用catkin编译如果你遇到如下错误: CMake error:System Error:No such file or ...

  5. point-position2修改版

    说明: 在共面直线测试中,由于计算误差等原因,共面条件判断不准,但计算结果依然正确. // point-position2.cpp : 定义控制台应用程序的入口点. #include "st ...

  6. django使用redis做缓存

    Django 使用 Redis 做缓存 django中应用redis:pip3 install django-redis - 配置 CACHES = { "default": { ...

  7. C#实现按键精灵的'找图' '找色' '找字'的功能

    http://www.cnblogs.com/JimmyBright/p/4355862.html 背景:游戏辅助功能通常使用按键精灵编写脚本,按键精灵的最大卖点就是能够找到画面中字,图,色,这对于模 ...

  8. hdu 5471(状压DP or 容斥)

    想了最复杂的思路,用了最纠结的方法,花了最长的时间,蒙了一种规律然后莫名其妙的过了. MD 我也太淼了. 后面想了下用状压好像还是挺好写的,而且复杂度也不高.推出的这个容斥的规律也没完全想透我就CAO ...

  9. <转> python的垃圾回收机制

    Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾.在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的 ...

  10. asp.net mvc4连接mysql

    环境:vs2013+mysql5.6+mysql connector for .net 6.8.3+MySQL for Visual Studio 1.1.3 参考:http://dev.mysql. ...