Pierwsze kroki

Wprowadzenie do Transformer obejmuje te czynności:

  1. Dodaj Media3 Transformer jako zależność w projekcie.
  2. Utwórz EditedMediaItem reprezentujący media do przetworzenia i zmiany, które mają zostać w nich wprowadzone.
  3. Utwórz Transformer, opisując wymagane dane wyjściowe i detektor zdarzeń zakończenia i 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 zgodnie z potrzebami. Możesz na przykład udostępnić wynik w innej aplikacji lub przesłać go na serwer.

Więcej informacji o tych krokach znajdziesz poniżej. Pełny przykład znajdziesz w TransformerActivityaplikacji demonstracyjnej przekształtnika.

Dodawanie Media3 Transformer jako zależności

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

Kotlin

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

Groovy

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

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

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Rozpoczynanie przekształcenia

Ten przykład pokazuje, jak utworzyć EditedMediaItem, aby usunąć dźwięk z pliku wejściowego, a następnie utworzyć i skonfigurować instancję Transformer, aby wyeksportować wideo w formacie H.265/HEVC i zapisać wynik 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 ExoPlayera. 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.

Na tej samej instancji możesz wykonywać kilka operacji eksportu po kolei, ale eksporty równoległe na tej samej instancji nie są obsługiwane.Transformer

Uwaga dotycząca wątków

Do instancji transformatora musi być dostęp z jednego wątku aplikacji, a metody odbiornika 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 komponent Transformer działa w tle i przesyła wywołania do metod odbiornika w wątku aplikacji.

Nasłuchiwanie zdarzeń

Metoda start jest asynchroniczna. Funkcja zwraca wartość natychmiast, a aplikacja jest powiadamiana o zdarzeniach za pomocą detektora 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 dla dźwięku i obrazu (w stosownych przypadkach).

Otrzymywanie informacji o postępach

Zadzwoń pod numer Transformer.getProgress, aby sprawdzić aktualny postęp transformacji. Zwrócona wartość wskazuje stan postępu. Jeśli stan postępu to PROGRESS_STATE_AVAILABLE, podana wartość ProgressHolder jest aktualizowana o bieżący procent postępu. Poniższy przykład pokazuje, jak okresowo sprawdzać postęp przekształcenia. Metodę updateProgressInUi można wdrożyć, aby aktualizować 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 eksportowania, anuluj operację eksportowania za pomocą ikony Transformer.cancel. Zasoby takie jak sprzętowe kodeki wideo są ograniczone, zwłaszcza na urządzeniach z niższej półki, więc warto to zrobić, aby zwolnić zasoby, jeśli dane wyjściowe nie są potrzebne.