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. 【藏】使用Entity Framework时要注意的一些性能问题

    这篇文章写的很好: http://diaosbook.com/Post/2012/12/9/performance-issue-in-select-one-or-few-colums-via-enti ...

  2. Package java.sql

    Provides the API for accessing and processing data stored in a data source (usually a relational dat ...

  3. python3----split and join

    s = "I am fine" s = s.split(" ") print(s) print("%".join(s)) results: ...

  4. LeetCode Problem 136:Single Number

    描述:Given an array of integers, every element appears twice except for one. Find that single one. Not ...

  5. 初探webpack之环境配置

    先感叹一句,前端的发展真是太快了,ng和bb还没怎么学好就要过时了.现在感觉react当是未来的一个大方向. 以前一直用的grunt,不过前段时间作者已经停止更新了.正好webpack风头正盛,咱也不 ...

  6. 《从零开始学Swift》学习笔记(Day 52)——Cocoa错误处理模式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift错误处理模式,在Swift 1.x和Swift 2.0是不同的两种模式. Swift 1.x代码错误处理模式采用Cocoa框架错误处理模式,到现 ...

  7. 160816、webpack 入门指南

    什么是 webpack? webpack是近期最火的一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX).coffee.样式(含less/sass).图片等都作为模块来使用和处理. 我们可以 ...

  8. js判断选择的时间是否大于今天

    获取的时间格式为  2012-5-28var thetime = document.getElementById("clearDate").value;var   d=new   ...

  9. Java中,由this关键字引发的问题

    很久之前一直有一个疑问,最近重新翻了遍JVM的书,才算是终于有所顿悟.问题如下: 被自己遗忘的问题 package org.hanyan.test.testClass; public class T3 ...

  10. Sql注入_mysql权限入侵

    实验:测试不同数据库用户的操作权限 文件读写测试:load_file() ,into outfile 数据库用户账号密码存储在mysql.user下 Mysql最高权限用户root: Mysql普通权 ...