Pierwsze kroki

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

  1. Dodaj Transformer Media3 jako zależność w projekcie.
  2. Utwórz obiekt EditedMediaItem reprezentujący media do przetworzenia i zmiany, które mają być do nich zastosowane.
  3. Utwórz Transformer z opisem wymaganych danych wyjściowych oraz odbiornikiem zdarzeń zakończenia i błędów.
  4. Rozpocznij operację eksportowania, przekazując EditedMediaItem, aby edytować, oraz ścieżkę wyjściową. Podczas eksportowania możesz przesłać zapytanie dotyczące bieżącego postępu lub anulować operację.
  5. Po zakończeniu eksportowania postępuj zgodnie z danymi wyjściowymi. Możesz na przykład udostępnić dane wyjściowe innej aplikacji lub przesłać je na serwer.

Czytaj dalej, aby poznać więcej szczegółów, a kompletny przykład znajdziesz w sekcji TransformerActivity w aplikacji demonstracyjnej transformer.

Dodaj transformater Media3 jako zależność

Najłatwiejszym sposobem rozpoczęcia korzystania z Transformera jest dodanie zależności Gradle w bibliotece do pliku build.gradle modułu aplikacji:

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")

Odlotowy

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

gdzie 1.3.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

Musisz ją włączyć we wszystkich plikach build.gradle zależnych od Transformera, dodając ten kod do sekcji android:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Rozpocznij przekształcenie

Oto przykład tworzenia reguły EditedMediaItem w celu usuwania dźwięku z pliku wejściowego, a następnie tworzenia i konfigurowania instancji Transformer do eksportowania plików wideo H.265/HEVC, które zwraca wynik do 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. Może to być strumień progresywny lub adaptacyjny, ale dane wyjściowe mają zawsze format progresywny. W przypadku adaptacyjnych danych wejściowych do przekształcenia są zawsze wybierane ścieżki o najwyższej rozdzielczości. Dane wejściowe mogą mieć dowolny format kontenera obsługiwany przez ExoPlayer, ale wyjściowym zawsze jest plik MP4.

W tej samej instancji Transformer możesz wykonać kilka operacji eksportu sekwencyjnie, ale jednoczesne eksporty z tą samą instancją nie są obsługiwane.

Uwaga dotycząca podziału na wątki

Dostęp do instancji transformera należy uzyskać z poziomu pojedynczego 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 metody detektora w wątku aplikacji.

Odsłuchiwanie zdarzeń

Metoda start jest asynchroniczna. Komunikat wraca 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);
      }
    };

Tag ExportResult zawiera informacje o pliku wyjściowym, w tym (w stosownych przypadkach) informacje o rozmiarze pliku i średniej szybkości transmisji bitów dla dźwięku i obrazu.

Otrzymuj powiadomienia o postępach

Wywołaj Transformer.getProgress, aby przesłać zapytanie o bieżący postęp przekształcenia. Zwrócona wartość wskazuje stan postępu. Jeśli stan postępu to PROGRESS_STATE_AVAILABLE, podany ProgressHolder jest aktualizowany o bieżącą wartość procentową postępu. Z przykładu poniżej dowiesz się, jak okresowo wysyłać zapytania o postęp przekształcenia, gdzie można wdrożyć metodę updateProgressInUi w celu 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ć dane z procesu eksportu, anuluj operację eksportu za pomocą funkcji Transformer.cancel. Zasoby takie jak sprzętowe kodeki wideo są ograniczone, zwłaszcza na słabszych urządzeniach, więc warto zrobić to, aby zwolnić zasoby, jeśli dane wyjściowe nie są potrzebne.