本文轉自: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 .