Iniziamo

Per iniziare a utilizzare Transformer devi svolgere i seguenti passaggi:

  1. Aggiungi Media3 Transformer come dipendenza nel progetto.
  2. Crea un EditedMediaItem che rappresenti i contenuti multimediali da elaborare e le modifiche da applicare.
  3. Crea un Transformer, descrivendo l'output richiesto e un listener per gli eventi di completamento ed errore.
  4. Avvia l'operazione di esportazione, trasmettendo il EditedMediaItem da modificare e un percorso di output. Durante l'esportazione, puoi eseguire query sull'avanzamento attuale o annullare l'operazione.
  5. Al termine dell'esportazione, gestisci l'output in base alle esigenze. Ad esempio, puoi condividere l'output su un'altra app o caricarlo su un server.

Continua a leggere per ulteriori dettagli su questi passaggi e guarda TransformerActivity nell'app demo di transformer per un esempio completo.

Aggiungi Media3 Transformer come dipendenza

Il modo più semplice per iniziare a utilizzare Transformer è aggiungere dipendenze gradle alla libreria nel file build.gradle del modulo dell'app:

Kotlin

implementation("androidx.media3:media3-transformer:1.3.1")
implementation("androidx.media3:media3-effect:1.3.1")
implementation("androidx.media3:media3-common:1.3.1")

trendy

implementation "androidx.media3:media3-transformer:1.3.1"
implementation "androidx.media3:media3-effect:1.3.1"
implementation "androidx.media3:media3-common:1.3.1"

dove 1.3.1 è la versione che preferisci. La versione più recente è disponibile consultando le note sulla versione.

Ulteriori informazioni sui moduli delle librerie disponibili sono disponibili nella pagina di Google Maven AndroidX Media3.

Attivare il supporto Java 8

Se non è già abilitato, devi attivare il supporto Java 8 in tutti i file build.gradle che dipendono da Transformer aggiungendo quanto segue alla sezione android:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Avvia una trasformazione

Ecco un esempio di creazione di un elemento EditedMediaItem per rimuovere l'audio da un file di input, quindi di creazione e configurazione di un'istanza Transformer per l'esportazione di video H.265/HEVC, generando il risultato in 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);

Per ulteriori informazioni sugli elementi multimediali, consulta la pagina degli elementi multimediali di ExoPlayer. L'input può essere un flusso progressivo o adattivo, ma l'output è sempre progressivo. Per gli input adattivi, vengono sempre selezionate le tracce con la risoluzione più alta. L'input può essere in qualsiasi formato container supportato da ExoPlayer, ma l'output è sempre un file MP4.

Puoi eseguire più operazioni di esportazione in sequenza sulla stessa istanza Transformer, ma le esportazioni simultanee con la stessa istanza non sono supportate.

Nota sull'organizzazione in thread

È necessario accedere alle istanze del trasformatore da un singolo thread dell'applicazione e i metodi di ascolto vengono chiamati sullo stesso thread. Nella maggior parte dei casi, il thread dell'applicazione può essere solo il thread principale. Internamente, Transformer svolge il suo lavoro in background e pubblica le sue chiamate ai metodi listener nel thread dell'applicazione.

Ascoltare eventi

Il metodo start è asincrono. Viene restituito immediatamente e l'app riceve notifiche relative agli eventi tramite il listener passato allo strumento di creazione 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 include informazioni sul file di output, tra cui le dimensioni del file e la velocità in bit media per audio e video, ove applicabile.

Ricevere aggiornamenti sui progressi

Chiama Transformer.getProgress per eseguire query sull'avanzamento attuale di una trasformazione. Il valore restituito indica lo stato di avanzamento. Se lo stato di avanzamento è PROGRESS_STATE_AVAILABLE, il valore ProgressHolder fornito viene aggiornato con la percentuale di avanzamento attuale. L'esempio seguente mostra come eseguire query periodiche sull'avanzamento di una trasformazione, in cui è possibile implementare il metodo updateProgressInUi per aggiornare una barra di avanzamento.

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);
        }
      }
    });

Annullare una trasformazione

Se l'utente sceglie di ritirarsi da un flusso di esportazione, annulla l'operazione di esportazione con Transformer.cancel. Le risorse come i codec video hardware sono limitate, soprattutto sui dispositivi di fascia bassa, quindi è importante farlo per liberare risorse se l'output non è necessario.