Pierwsze kroki z Transformer obejmują te czynności:
- Dodaj Media3 Transformer jako zależność w projekcie.
- Utwórz
EditedMediaItemreprezentujący multimedia do przetworzenia i zmiany, które mają zostać zastosowane. - Utwórz
Transformer, opisując wymagane dane wyjściowe i detektor zdarzeń zakończenia i błędów. - Rozpocznij eksport, przekazując
EditedMediaItemdo edycji i ścieżkę wyjściową. Podczas eksportu możesz sprawdzić bieżący postęp lub anulować operację. - 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.