2016-05-30 94 views
1

我有一串H264視頻,需要在我的Android應用程序中顯示。如果我將MediaCodec與表面配置在一起,那麼視頻就會被解碼到我的應用中,沒有問題,我可以在這個表面看到它。將H264幀解碼爲字節數組

但我還需要在某些時刻獲取視頻的位圖(即將某些幀存儲在SD卡上)。是否有可能配置MediaCodec庫返回一個字節數組,而不是直接面向表面?

另一種選擇是直接從表面獲取位圖,但我在SDK上也找不到這個選項。

回答

1

您可以使用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);跳過整個位圖轉換過程。

+0

但這並不做什麼,我什麼:我有一個H264流,我想直接解碼爲字節的緩衝區,避免任何UI組件。 –

+0

這個問題沒有提到目標作爲字節數據的檢索和UI的缺席,你應該讓你的問題更清楚。無論如何,檢查修改的答案,看看它是否符合您的需求。 – Kai

+0

我想你是對的,我的問題沒有妥善制定。我需要抓取用戶當前正在查看的任何東西(在由MediaCodec渲染的SurfaceView中)作爲快照。 –

-3

試試這個:

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); 
    } 

}

+0

這與我的問題無關。 –