我有一串H264視頻,需要在我的Android應用程序中顯示。如果我將MediaCodec與表面配置在一起,那麼視頻就會被解碼到我的應用中,沒有問題,我可以在這個表面看到它。將H264幀解碼爲字節數組
但我還需要在某些時刻獲取視頻的位圖(即將某些幀存儲在SD卡上)。是否有可能配置MediaCodec庫返回一個字節數組,而不是直接面向表面?
另一種選擇是直接從表面獲取位圖,但我在SDK上也找不到這個選項。
我有一串H264視頻,需要在我的Android應用程序中顯示。如果我將MediaCodec與表面配置在一起,那麼視頻就會被解碼到我的應用中,沒有問題,我可以在這個表面看到它。將H264幀解碼爲字節數組
但我還需要在某些時刻獲取視頻的位圖(即將某些幀存儲在SD卡上)。是否有可能配置MediaCodec庫返回一個字節數組,而不是直接面向表面?
另一種選擇是直接從表面獲取位圖,但我在SDK上也找不到這個選項。
您可以使用MediaMetadataRetriever:
MediaMetadataRetriever mediaMetadataRetriever=new MediaMetadataRetriever(); //should be stored as an instance variable
mediaMetadataRetriever.setDataSource(mVideo.getVideoUrl(Video.SD));
int time = videoView.getCurrentPosition()* 1000; //micro-to-milliseconds
Bitmap bmFrame = mediaMetadataRetriever.getFrameAtTime(time);
編輯:
要獲取原始字節數據,而UI的參與,您可以通過幀前進的時間框架,得到了位圖,並將其轉換爲字節數組。
爲了更有效率,考慮分叉FFmpegMediaMetadataRetriever,其FFmpegMediaMetadataRetriever.java
方法private native byte [] _getFrameAtTime(long timeUs, int option);
跳過整個位圖轉換過程。
試試這個:
public class GameView extends SurfaceView {
private Bitmap bmp;
private SurfaceHolder holder;
public GameView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas(null);
onDraw(c);
holder.unlockCanvasAndPost(c);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(bmp, 10, 10, null);
}
}
這與我的問題無關。 –
但這並不做什麼,我什麼:我有一個H264流,我想直接解碼爲字節的緩衝區,避免任何UI組件。 –
這個問題沒有提到目標作爲字節數據的檢索和UI的缺席,你應該讓你的問題更清楚。無論如何,檢查修改的答案,看看它是否符合您的需求。 – Kai
我想你是對的,我的問題沒有妥善制定。我需要抓取用戶當前正在查看的任何東西(在由MediaCodec渲染的SurfaceView中)作爲快照。 –