Pierwsze kroki

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

  1. Dodaj Media3 Transformer jako zależność w projekcie.
  2. Utwórz obiekt EditedMediaItem reprezentujący multimedia do przetworzenia i zmiany, które chcesz wprowadzić.
  3. Utwórz obiekt Transformer, opisując wymagane dane wyjściowe i detektor zdarzeń zakończenia i błędu.
  4. Rozpocznij operację eksportu, 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 zgodnie z potrzebami. Możesz na przykład udostępnić dane wyjściowe innej aplikacji lub przesłać je na serwer.

Czytaj dalej, aby dowiedzieć się więcej o tych krokach, i zapoznaj się z TransformerActivity w aplikacji demonstracyjnej Transformer, aby zobaczyć kompletny przykład.

Dodawanie Media3 Transformer jako zależności

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

Kotlin

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

Dynamiczny

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

gdzie 1.11.1 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 obsługa Javy 8 nie jest jeszcze włączona, musisz ją włączyć we wszystkich plikach build.gradle, które zależą od Transformer, dodając do sekcji android ten kod:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Rozpoczynanie przekształcenia

Oto przykład tworzenia obiektu EditedMediaItem w celu usunięcia dźwięku z pliku wejściowego, a następnie tworzenia i konfigurowania instancji Transformer do eksportowania filmu H.265/HEVC i zapisywania wyniku w 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 ExoPlayer poświęconej elementom multimedialnym. Dane wejściowe mogą być strumieniem progresywnym lub adaptacyjnym, ale dane wyjściowe są zawsze strumieniem progresywnym. W przypadku wejść adaptacyjnych do przekształcenia zawsze wybierane są ścieżki o najwyższej rozdzielczości. Dane wejściowe mogą być w dowolnym formacie kontenera obsługiwanym przez ExoPlayer, ale dane wyjściowe są zawsze plikiem MP4.

Możesz wykonywać wiele operacji eksportu sekwencyjnie w tej samej instancji Transformer, ale jednoczesne eksporty w tej samej instancji nie są obsługiwane.

Informacje o generowaniu multimediów wygenerowanych przez AI przez łączenie wielu danych wejściowych znajdziesz w artykule Edytowanie wielu komponentów.

Uwaga dotycząca wątków

Dostęp do instancji Transformer musi być uzyskiwany z jednego wątku aplikacji, a metody detektora są wywoływane w tym samym wątku. W większości przypadków wątek aplikacji może być po prostu jej głównym wątkiem. Wewnętrznie Transformer działa w tle i publikuje wywołania metod detektora w wątku aplikacji.

Nasłuchiwanie zdarzeń

Metoda start jest asynchroniczna. Zwraca ona wynik natychmiast, a aplikacja jest powiadamiana o zdarzeniach przez detektor przekazany 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 o jego rozmiarze i średniej szybkości transmisji bitów audio i wideo (w zależności od przypadku).

Otrzymywanie informacji o postępach

Wywołaj Transformer.getProgress, aby sprawdzić bieżący postęp przekształcenia. Zwrócona wartość wskazuje stan postępu. Jeśli stan postępu to PROGRESS_STATE_AVAILABLE, podany parametr ProgressHolder jest aktualizowany o bieżący procent postępu. Poniższy przykład pokazuje, jak okresowo sprawdzać postęp przekształcania. Metoda updateProgressInUi może służyć do aktualizowania 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 eksportowania, anuluj operację eksportowania za pomocą metody Transformer.cancel. Zasoby takie jak sprzętowe kodeki wideo są ograniczone, zwłaszcza na urządzeniach niższej klasy, dlatego ważne jest, aby zwolnić zasoby, jeśli dane wyjściowe nie są potrzebne.