Android MediaCodec: Reduce el tamaño del video mp4

Estoy buscando una manera de "comprimir" un video mp4. Para lograr esto, quiero reducir la resolución del video y / o reducir FPS.

Después de una larga investigación, creo que la forma de hacerlo es usar MediaCodec y las API relacionadas como sigue:

-> MediaExtractor para extraer datos de medios codificados de un archivo mp4. -> MediaCodec (decodificador): Decodificar cada fotograma para un procesamiento posterior. -> MediaCodec (Encoder): En este punto, supongo que es donde deberíamos establecer los parámetros de MediaFormat como la resolución de vídeo, que debería ayudarnos a reducir el tamaño final del archivo mp4. -> MediaMuxer para generar archivos mp4 (MinSDK 18, esto podría ser un problema, pero por ahora … ok).

No quiero usar un SurfaceView / TextureView. En cuanto al audio, no quiero procesarlo para reducir la calidad.

He estado viendo todos los ejemplos aquí: http://bigflake.com/mediacodec/

También he visto CTS módulos de código fuente.

Y he estado viendo varios proyectos como estos: https://github.com/vecio/MediaCodecDemo/blob/master/src/io/vec/demo/mediacodec/DecodeActivity.java

Y por supuesto he leído decenas de mensajes en stackoverflow.

El problema es que todavía no he encontrado ningún ejemplo de código que funcione bien para este porpuse. Traté de tomar varias piezas de código y ponerlas juntas en un proyecto, pero realmente no funciona.

Gracias.

Lo más parecido a lo que quieres es probablemente el DecodeEditEncodeTest en bigflake. No necesitas SurfaceView o TextureView , ya que no estás intentando mostrar el video, pero necesitarás usar SurfaceTexture .

El código de prueba genera un video, luego decodifica / edita / codifica, y luego prueba la salida codificada. Desea la parte decodificar-editar-codificar. Al crear el codificador, dale el tamaño que quieras. La superficie de entrada que cree tendrá un tamaño adecuado. La escala se realiza mediante la GPU, ya que transforma la textura GL (desde SurfaceTexture ) en la superficie de entrada del codificador. Tendrá que decidir si el filtrado lineal de GLES proporciona el nivel de calidad que necesita.

(Puedes ver algo similar en ExtractMpegFramesTest , que escala todo a 640×480 como lo está haciendo la extracción.En este caso, es la conversión de los fotogramas a PNG en lugar de alimentarlos en un codificador, por lo que no es aplicable a su situación.

Soltar cuadros es teóricamente fácil: simplemente no lo envíe al codificador. En la práctica es un poco más difícil si la entrada tiene cuadros espaciados de forma irregular. Si la entrada es "frame1 frame2 … pause … frame4 frame5", y dejas caer frame2, terminarás pausado en frame1, lo que podría parecer extraño. Puede usar los sellos de tiempo de presentación para determinar el momento.

La entrada de superficie y MediaMuxer (necesarios para guardar H.264 como .mp4) requieren API 18+. Para versiones anteriores de Android es probable que desee utilizar una biblioteca de terceros como ffmpeg .

  • Compresión de video en android usando la nueva biblioteca de MediaCodec
  • Recibir y decodificar H.264 en vivo en Android
  • Android: Quiero grabar una alimentación de vídeo de baja calidad y enviarla en paquetes discretos. ¿Es posible? ¿Cómo lo abordarías?
  • Reproductor de vídeo flotante (como el reproductor de youtube) en android
  • Uso de surfaceView para capturar un video
  • Programe para comprimir el video sin FFMPEG en Android
  • ¿Por qué `` OnInfoListener` de MediaRecorder no se llama en código inferior cuando se alcanza el tamaño máximo de archivo
  • Maneras alternativas de establecer durationLimit o sizeLimit durante la grabación de vídeo?
  • Android - Cómo iniciar la grabación de vídeo automáticamente cuando se llama a la cámara intención
  • Comprimir video como whatsapp
  • Cómo fusionar el archivo de audio con un nuevo archivo de vídeo? ¿Es posible en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.