2016-05-30 57 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

这与我的问题无关。 –