Pierwsze kroki

Pierwsze kroki z Transformer obejmują te czynności:

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

Więcej informacji o tych krokach znajdziesz poniżej. Pełny przykład znajdziesz w TransformerActivity w aplikacji demonstracyjnej Transformer.

Dodawanie Media3 Transformer jako zależności

Najłatwiej zacząć korzystać z Transformer, dodając zależności Gradle do biblioteki w pliku build.gradle modułu aplikacji:

Kotlin

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

Groovy

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

gdzie 1.9.3 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ę Javy 8 we wszystkich plikach build.gradle, które zależą od Transformer, dodając do sekcji android te wiersze:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Rozpoczynanie przekształcenia

Oto przykład tworzenia EditedMediaItem w celu usunięcia dźwięku z pliku wejściowego, a następnie tworzenia i konfigurowania instancji Transformer w celu wyeksportowania filmu H.265/HEVC i zapisania 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 Elementy multimedialne ExoPlayer page. Dane wejściowe mogą być strumieniem progresywnym lub adaptacyjnym, ale dane wyjściowe są zawsze strumieniem progresywnym. W przypadku danych wejściowych 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ć kilka operacji eksportu sekwencyjnie na tej samej instancji Transformer, ale eksporty współbieżne z tą samą instancją nie są obsługiwane.

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 głównym wątkiem aplikacji. Wewnętrznie Transformer wykonuje swoją pracę w tle i wysyła wywołania do metod detektora w wątku aplikacji.

Nasłuchiwanie zdarzeń

Metoda start jest asynchroniczna. Zwraca ona natychmiastową wartość, a aplikacja jest powiadamiana o zdarzeniach za pomocą odbiornika przekazanego do konstruktora 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 oraz średnie szybkości transmisji bitów dźwięku i obrazu.

Otrzymywanie aktualizacji postępu

Aby sprawdzić bieżący postęp przekształcenia, wywołaj Transformer.getProgress. Zwracana wartość wskazuje stan postępu. Jeśli stan postępu to PROGRESS_STATE_AVAILABLE, podany ProgressHolder jest aktualizowany o bieżący procent postępu. Poniższy przykład pokazuje, jak okresowo sprawdzać postęp przekształcenia. Metodę updateProgressInUi można zaimplementować tak, aby aktualizowała pasek 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 sprzętowe kodeki wideo, są ograniczone, zwłaszcza na urządzeniach z niższej półki, dlatego ważne jest, aby to zrobić, aby zwolnić zasoby, jeśli dane wyjściowe nie są potrzebne.