本文轉自:http://blog.csdn.net/heart_Moving/article/details/17414067
今天做Android視頻文件解碼,需求:從一個視頻文件獲取到一幀一幀的圖片。
總結如下:
首先看代碼:
MediaDecoder.java
- 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;
- }
- }
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 .

