Para comenzar a usar Transformer
, sigue estos pasos:
- Agrega Media3 Transformer como una dependencia en tu proyecto.
- Compila un
EditedMediaItem
que represente el contenido multimedia que se procesará y las ediciones que se le aplicarán. - Compila un
Transformer
que describa el resultado requerido y un objeto de escucha para eventos de finalización y error. - Inicia la operación de exportación y pasa el
EditedMediaItem
para editar y una ruta de salida. Durante la exportación, puedes consultar el progreso actual o cancelar la operación. - Cuando finalice la exportación, controla el resultado según sea necesario. Por ejemplo, puedes compartir el resultado con otra app o subirlo a un servidor.
Sigue leyendo para obtener más detalles sobre estos pasos y consulta TransformerActivity
en la app de demostración de transformadores para ver un ejemplo completo.
Agrega Media3 Transformer como una dependencia
La manera más fácil de comenzar a usar Transformer es agregar dependencias de Gradle en la biblioteca, en el archivo build.gradle
del módulo de tu app:
Kotlin
implementation("androidx.media3:media3-transformer:1.4.1") implementation("androidx.media3:media3-effect:1.4.1") implementation("androidx.media3:media3-common:1.4.1")
Groovy
implementation "androidx.media3:media3-transformer:1.4.1" implementation "androidx.media3:media3-effect:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
en la que 1.4.1 es tu versión preferida. Para encontrar la versión más reciente, consulta las notas de la versión.
Puedes encontrar más información sobre los módulos de biblioteca disponibles en la página Media3 de AndroidX de Google Maven.
Cómo activar la compatibilidad con Java 8
Si aún no lo hiciste, debes habilitar la compatibilidad con Java 8 en todos los archivos build.gradle
que dependen de Transformer. Para ello, agrega lo siguiente a la sección android
:
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
}
Cómo iniciar una transformación
A continuación, se muestra un ejemplo de cómo crear un EditedMediaItem
para quitar el audio de un archivo de entrada y, luego, crear y configurar una instancia de Transformer
para exportar video H.265/HEVC y enviar el resultado a outputPath
.
Kotlin
val inputMediaItem = MediaItem.fromUri("path_to_input_file") val editedMediaItem = EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build() val transformer = Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .addListener(transformerListener) .build() transformer.start(editedMediaItem, outputPath)
Java
MediaItem inputMediaItem = MediaItem.fromUri("path_to_input_file"); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build(); Transformer transformer = new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .addListener(transformerListener) .build(); transformer.start(editedMediaItem, outputPath);
Para obtener más información sobre los elementos multimedia, consulta la página de elementos multimedia de ExoPlayer. La entrada puede ser una transmisión progresiva o adaptativa, pero la salida siempre es una transmisión progresiva. En el caso de las entradas adaptables, siempre se seleccionan las pistas de mayor resolución para la transformación. La entrada puede ser de cualquier formato de contenedor que admita ExoPlayer, pero el resultado siempre es un archivo MP4.
Puedes ejecutar varias operaciones de exportación de forma secuencial en la misma instancia de Transformer
, pero no se admiten las exportaciones simultáneas con la misma instancia.
Nota sobre los subprocesos
Se debe acceder a las instancias de Transformer desde un solo subproceso de la aplicación, y se llama a los métodos de escucha en el mismo subproceso. En la mayoría de los casos, el subproceso de la aplicación puede ser solo el subproceso principal de la aplicación. De forma interna, Transformer realiza su trabajo en segundo plano y publica sus llamadas a los métodos de objetos de escucha en el subproceso de la aplicación.
Cómo escuchar eventos
El método start
es asíncrono. Se muestra de inmediato y se notifica a la app sobre los eventos a través del objeto de escucha que se pasa al compilador de Transformer
.
Kotlin
val transformerListener: Transformer.Listener = object : Transformer.Listener { override fun onCompleted(composition: Composition, result: ExportResult) { playOutput() } override fun onError(composition: Composition, result: ExportResult, exception: ExportException) { displayError(exception) } }
Java
Transformer.Listener transformerListener = new Transformer.Listener() { @Override public void onCompleted(Composition composition, ExportResult result) { playOutput(); } @Override public void onError(Composition composition, ExportResult result, ExportException exception) { displayError(exception); } };
ExportResult
incluye información sobre el archivo de salida, incluido el tamaño del archivo y las tasas de bits promedio de audio y video, según corresponda.
Cómo recibir actualizaciones del progreso
Llama a Transformer.getProgress
para consultar el progreso actual de una transformación. El valor que se muestra indica el estado de progreso. Si el estado de progreso es PROGRESS_STATE_AVAILABLE
, el ProgressHolder
proporcionado se actualiza con el porcentaje de progreso actual. En el siguiente ejemplo, se muestra cómo consultar periódicamente el progreso de una transformación, en la que se puede implementar el método updateProgressInUi
para actualizar una barra de progreso.
Kotlin
transformer.start(inputMediaItem, outputPath) val progressHolder = ProgressHolder() mainHandler.post( object : Runnable { override fun run() { val progressState: @ProgressState Int = transformer.getProgress(progressHolder) updateProgressInUi(progressState, progressHolder) if (progressState != Transformer.PROGRESS_STATE_NOT_STARTED) { mainHandler.postDelayed(/* r= */this, /* delayMillis= */500) } } } )
Java
transformer.start(inputMediaItem, outputPath); ProgressHolder progressHolder = new ProgressHolder(); mainHandler.post( new Runnable() { @Override public void run() { @Transformer.ProgressState int progressState = transformer.getProgress(progressHolder); updateProgressInUi(progressState, progressHolder); if (progressState != PROGRESS_STATE_NOT_STARTED) { mainHandler.postDelayed(/* r= */ this, /* delayMillis= */ 500); } } });
Cómo cancelar una transformación
Si el usuario decide retirarse de un flujo de exportación, cancela la operación de exportación con Transformer.cancel
. Los recursos, como los códecs de video de hardware, son limitados, en especial en dispositivos de gama baja, por lo que es importante hacerlo para liberar recursos si no se necesita el resultado.