Pierwsze kroki

Aby zacząć korzystać z Transformer:

  1. Dodaj Media3 Transformer jako zależność w projekcie.
  2. Utwórz obiekt EditedMediaItem reprezentujący multimedia do przetworzenia i edycji, aby go zastosować.
  3. Utwórz obiekt Transformer opisujący wymagane dane wyjściowe oraz detektor zdarzeń ukończenia i błędów.
  4. Uruchom operację eksportu, podając EditedMediaItem, aby edytować, oraz ścieżkę wyjściową. Podczas eksportowania możesz przesłać zapytanie o bieżący postęp lub anulować operację.
  5. Po zakończeniu eksportowania obsługuj 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 czynnościach, a pełny przykład znajdziesz w sekcji TransformerActivity dostępnej w aplikacji demonstracyjnej transformera.

Dodaj Media3 Transformer jako zależność

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.3.1")
implementation("androidx.media3:media3-effect:1.3.1")
implementation("androidx.media3:media3-common:1.3.1")

Odlotowe

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. Najnowsza wersja jest dostępna w informacjach o wersjach.

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

Włącz obsługę języka Java 8

Musisz włączyć obsługę języka Java 8 we wszystkich plikach build.gradle, które korzystają z Transformera, dodając do sekcji android ten kod:

compileOptions {
  targetCompatibility JavaVersion.VERSION_1_8
}

Rozpocznij przekształcanie

Oto przykład tworzenia obiektu EditedMediaItem w celu usunięcia dźwięku z pliku wejściowego, a następnie utworzenia i skonfigurowania instancji Transformer na potrzeby eksportowania wideo H.265/HEVC, z wykorzystaniem formatu 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 w odtwarzaczu ExoPlayer. Dane wejściowe mogą być strumieniem progresywnym lub adaptacyjnym, ale dane wyjściowe to zawsze strumień progresywny. W przypadku adaptacyjnych danych wejściowych zawsze wybierane są ścieżki o najwyższej rozdzielczości. Dane wejściowe mogą mieć dowolny format kontenera obsługiwany przez ExoPlayer, ale dane wyjściowe zawsze to plik MP4.

W tej samej instancji Transformer możesz wykonać kilka operacji eksportu jednocześnie, ale równocześnie eksporty z tą samą instancją nie są obsługiwane.

Uwaga na temat tworzenia wątków

Dostęp do instancji transformera musi być możliwy 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ć tylko głównym wątkiem aplikacji. Wewnętrznie Transformer wykonuje pracę w tle i publikuje wywołania metod detektora w wątku aplikacji.

Wykrywaj zdarzenia

Metoda start jest asynchroniczna. Jest on zwracany 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 rozmiar pliku oraz średnią szybkość transmisji bitów dźwięku i wideo.

Otrzymuj powiadomienia o postępach

Wywołaj Transformer.getProgress, aby przesłać zapytanie o bieżący postęp transformacji. Zwrócona wartość wskazuje stan postępu. Jeśli stan postępu to PROGRESS_STATE_AVAILABLE, wartość w polu ProgressHolder jest aktualizowana o aktualny odsetek postępu. Poniższy przykład pokazuje, jak okresowo wysyłać zapytania o postęp przekształcenia, gdzie można wdrożyć metodę updateProgressInUi, 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łcania

Jeśli użytkownik zdecyduje się wycofać proces eksportu, anuluj operację eksportu za pomocą funkcji Transformer.cancel. Zasoby takie jak sprzętowe kodeki wideo są ograniczone, zwłaszcza na mniej zaawansowanych urządzeniach, więc warto to zrobić, aby zwolnić zasoby, gdy dane wyjściowe nie są potrzebne.