[转]android 获取视频帧

时间:2023-03-09 19:40:58
[转]android 获取视频帧

本文转自:http://blog.****.net/heart_Moving/article/details/17414067

今天做Android视频文件解码,需求:从一个视频文件获取到一帧一帧的图片。

总结如下:

首先看代码:

MediaDecoder.java

  1. import android.graphics.Bitmap;
  2. import android.media.MediaMetadataRetriever;
  3. import android.util.Log;
  4. public class MediaDecoder {
  5. private static final String TAG = "MediaDecoder";
  6. private MediaMetadataRetriever retriever = null;
  7. private String fileLength;
  8. public MediaDecoder(String file) {
  9. if(CommonUtils.checkFile(file)){
  10. retriever = new MediaMetadataRetriever();
  11. retriever.setDataSource(file);
  12. fileLength = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
  13. Log.i(TAG, "fileLength : "+fileLength);
  14. }
  15. }
  16. /**
  17. * 获取视频某一帧
  18. * @param timeMs 毫秒
  19. * @param listener
  20. */
  21. public boolean decodeFrame(long timeMs,OnGetBitmapListener listener){
  22. if(retriever == null) return false;
  23. Bitmap bitmap = retriever.getFrameAtTime(timeMs * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
  24. if(bitmap == null) return false;
  25. listener.getBitmap(bitmap, timeMs);
  26. return true;
  27. }
  28. /**
  29. * 取得视频文件播放长度
  30. * @return
  31. */
  32. public String getVedioFileLength(){
  33. return fileLength;
  34. }
  35. }
[转]android 获取视频帧
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.util.Log; public class MediaDecoder {
private static final String TAG = "MediaDecoder";
private MediaMetadataRetriever retriever = null;
private String fileLength; public MediaDecoder(String file) {
if(CommonUtils.checkFile(file)){
retriever = new MediaMetadataRetriever();
retriever.setDataSource(file);
fileLength = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
Log.i(TAG, "fileLength : "+fileLength);
}
}
/**
* 获取视频某一帧
* @param timeMs 毫秒
* @param listener
*/
public boolean decodeFrame(long timeMs,OnGetBitmapListener listener){
if(retriever == null) return false;
Bitmap bitmap = retriever.getFrameAtTime(timeMs * 1000, MediaMetadataRetriever.OPTION_CLOSEST);
if(bitmap == null) return false;
listener.getBitmap(bitmap, timeMs);
return true;
}
/**
* 取得视频文件播放长度
* @return
*/
public String getVedioFileLength(){
return fileLength;
} }

这里是获取视频帧工具,调试的时候遇到一些问题:

其中一个是getFrameAtTime参数的使用,先看方法原型:public Bitmap getFrameAtTime(long timeUs, int option) 第一个参数是传入时间,只能是us(微秒) ,当时我传入的ms,获取的总是第一帧,所以这个问题都弄了好久。

然后是第二个参数,先看看官方解释:

OPTION_CLOSEST    在给定的时间,检索最近一个帧,这个帧不一定是关键帧。

OPTION_CLOSEST_SYNC    在给定的时间,检索最近一个同步与数据源相关联的的帧(关键帧)。

OPTION_NEXT_SYNC  在给定时间之后检索一个同步与数据源相关联的关键帧。

OPTION_PREVIOUS_SYNC   顾名思义,同上

这里为了提取我们想要的帧,不使用关键帧,所以用 OPTION_CLOSEST .