Pierwsze kroki

Aby rozpocząć korzystanie z Transformer, wykonaj te czynności:

  1. Dodaj Media3 Transformer jako zależność w projekcie.
  2. Utwórz EditedMediaItem reprezentujący multimedia do przetworzenia i edycje, które mają zostać zastosowane.
  3. Utwórz element Transformer, który opisuje wymagane dane wyjściowe i detektor zdarzeń zakończenia oraz błędów.
  4. Rozpocznij operację eksportowania, przekazując EditedMediaItem do edycji i ścieżkę wyjściową. Podczas eksportowania możesz sprawdzić bieżący postęp lub anulować operację.
  5. Po zakończeniu eksportowania przetwórz dane wyjściowe w odpowiednim celu. Możesz na przykład udostępnić dane wyjściowe innej aplikacji lub przesłać je na serwer.

Poniżej znajdziesz więcej informacji o tych krokach, a w aplikacji demo Transformer możesz zobaczyć kompletny przykład.TransformerActivity

Dodawanie modułu Media3 Transformer jako zależności

Najprostszym sposobem na rozpoczęcie korzystania z Transformera jest dodanie zależności Gradle biblioteki w pliku build.gradle modułu aplikacji:

Kotlin

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

Groovy

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

gdzie 1.5.0 to preferowana wersja. Najnowszą wersję znajdziesz w informacjach o wersji.

Więcej informacji o dostępnych modułach biblioteki znajdziesz na stronie Google Maven AndroidX Media3.

Włączanie obsługi Javy 8

Jeśli nie jest jeszcze włączona, musisz włączyć obsługę Java 8 we wszystkich plikach build.gradle, które zależą od funkcji Transformer. W tym celu dodaj do sekcji android następujący kod:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Rozpoczynanie przekształcenia

Oto przykład utworzenia obiektu EditedMediaItem, aby usunąć dźwięk z pliku wejściowego, a następnie utworzyć i skonfigurować instancję Transformer, aby wyeksportować wideo H.265/HEVC i przekazać wynik do obiektu 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);

Więcej informacji o elementach multimedialnych znajdziesz na stronie elementów multimedialnych ExoPlayer. Dane wejściowe mogą być strumieniowane progresywnie lub adaptacyjnie, ale dane wyjściowe są zawsze strumieniowane progresywnie. W przypadku danych adaptacyjnych do przekształcania zawsze wybierane są ścieżki o najwyższej rozdzielczości. Dane wejściowe mogą mieć dowolny format kontenera obsługiwany przez ExoPlayera, ale dane wyjściowe to zawsze plik MP4.

Na tej samej instancji Transformer możesz wykonywać sekwencyjnie wiele operacji eksportu, ale nie można eksportować jednocześnie z tej samej instancji.

Uwaga na temat wątków

Do instancji transformatora można uzyskać dostęp z jednego wątku aplikacji, a metody listenera są wywoływane w tym samym wątku. W większości przypadków wątek aplikacji może być wątkiem głównym aplikacji. Wewnętrznie Transformer wykonuje swoje zadania w tle i wysyła wywołania do metod listenera w wątku aplikacji.

Słuchanie zdarzeń

Metoda start jest asynchroniczna. Zwracany jest natychmiast, a aplikacja jest powiadamiana o zdarzeniach za pomocą detektora przekazanego do kreatora 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 zawiera informacje o pliku wyjściowym, w tym jego rozmiar i średnią szybkość transmisji danych dźwięku i obrazu (w odpowiednich przypadkach).

otrzymywać informacje o postępach,

Aby sprawdzić bieżący postęp transformacji, wywołaj funkcję Transformer.getProgress. Zwrócona wartość wskazuje stan postępu. Jeśli stan postępu to PROGRESS_STATE_AVAILABLE, podana wartość ProgressHolder jest aktualizowana o bieżący odsetek postępu. Ten przykład pokazuje, jak okresowo wysyłać zapytania o postęp transformacji. W tym celu możesz zastosować metodę updateProgressInUi, która umożliwia aktualizowanie paska postępu.

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

Anulowanie przekształcenia

Jeśli użytkownik zdecyduje się wycofać z procesu eksportu, anuluj operację eksportu za pomocą Transformer.cancel. Zasoby takie jak kodeki wideo sprzętowe są ograniczone, zwłaszcza na urządzeniach niższych klas, dlatego ważne jest, aby je zwolnić, jeśli nie są potrzebne.