2016-05-30 4 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); 

Edit:

Для получения исходных данных байт без участия интерфейса, вы можете заранее время, кадр за кадром, получить Bitmap и преобразовать его в байтовый массив.

Чтобы быть более эффективным, рассмотрите forking FFmpegMediaMetadataRetriever, у которого FFmpegMediaMetadataRetriever.java есть способ private native byte [] _getFrameAtTime(long timeUs, int option);, пропускающий весь процесс преобразования Bitmap.

+0

Но это не то, что я, что: у меня есть поток H264, и я хочу, чтобы декодировать непосредственно в буфер байтов, избегая любой компонент пользовательского интерфейса. –

+0

Вопрос не упоминал цель как извлечение байтовых данных и отсутствие пользовательского интерфейса, вы должны сделать свой вопрос более ясным. Независимо от того, проверьте измененный ответ, чтобы убедиться, что он соответствует вашим потребностям. – Kai

+0

Я думаю, вы правы, мой вопрос не был правильно сформулирован. Мне нужно захватить все, что пользователь просматривает (в SurfaceView, созданный MediaCodec) в качестве моментального снимка. –

-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

Это не имеет никакого отношения к моему вопросу. –

Смежные вопросы