android video bitmap mediacodec mediaextractor

android - Use MediaCodec y MediaExtractor para decodificar y codificar video



bitmap (2)

Necesito decodificar un video en una secuencia de bitmaps, de modo que pueda modificarlos y luego comprimirlos en un archivo de video en Android.

Planeo administrar esto usando getFrameAtTime y guardándolo en una secuencia de imágenes. Luego puedo modificar las imágenes en la secuencia y codificarla para volver a una película. Pero tengo dos problemas con esto:

  • Primero, mientras lo leo, getFrameAtTime es para crear miniaturas y no garantiza la devolución del fotograma correcto. Esto hace que el video sea lento.
  • En segundo lugar, guardar las imágenes y leerlas lleva mucho tiempo.

Leí que la forma correcta de hacer la decodificación es con MediaExtractor, esto está bien, pero solo tengo ejemplos para renderizarlo directamente en un surfaceView . ¿Hay alguna forma de convertir el outputBuffer en un mapa de bits?

Lo necesitaría para que funcione con un nivel de API de 16 o superior.


Puede encontrar una colección de ejemplos útiles en el sitio de bigflake .

En particular, ExtractMpegFramesTest demuestra cómo decodificar un archivo .mp4 a Bitmap , y DecodeEditEncodeTest decodifica y vuelve a codificar una secuencia H.264, modificando los cuadros con un sombreado GLES.

Muchos de los ejemplos usan características introducidas en API 18, como Surface entrada de Surface a MediaCodec (que evita una serie de problemas de formato de color) y MediaMuxer (que le permite convertir la corriente elemental H.264 sin formato que sale de MediaCodec en una archivo .mp4). Algunos dispositivos le permitirán extraer video a datos YUV en ByteBuffer , modificarlo y volver a codificarlo, pero otros dispositivos extraen formatos de color YUV patentados que pueden ser rechazados por la versión API 16 de MediaCodec .

Recomiendo la codificación de API 18 (Android 4.3 "Jellybean" MR2) o posterior.


Hay muchas personas que dicen que el método onFrameAvailable() nunca se llama. Bueno, el oyente debe estar en un hilo diferente al hilo principal. Para configurar el oyente haga esto: (donde este es el oyente de la clase que implementa SurfaceTexture.IOnFrameAvailableListener ):

mSurfaceTexture.SetOnFrameAvailableListener(this);