転載元:https://blog.csdn.net/heart_Moving/article/details/17414067
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;
}
}
ビデオ フレームを取得するためのツールを次に示します。デバッグ中にいくつかの問題が発生しました。
それらの 1 つは getFrameAtTime パラメータの使用です. まずメソッド プロトタイプを見てください: public Bitmap getFrameAtTime(long timeUs, int option) 最初のパラメータは着信時間で、それは us (マイクロ秒) のみです. そのとき、渡された ms が得られたのは常に最初のフレームなので、私はこの問題に長い間取り組んできました。
次に、2番目のパラメーターがあります。最初に公式の説明を見てください。
OPTION_CLOSEST ある時点で、必ずしもキー フレームではない最新のフレームを取得します。
OPTION_CLOSEST_SYNC 所定の時間に、データ ソースに関連付けられた最新の同期フレーム (キーフレーム) を取得します。
OPTION_NEXT_SYNC は、 指定された時間後にデータソースに関連付けられた同期キーフレームを取得します。
OPTION_PREVIOUS_SYNC は 、名前が示すように、上記と同じです
ここで必要なフレームを抽出するために、キーフレームは使用されないため、OPTION_CLOSEST が使用されます。
OnGetBitmapListener.java
import android.graphics.Bitmap;
public interface OnGetBitmapListener {
void getBitmap(Bitmap bitmap, long timeMs);
}