Aby rozpocząć korzystanie z Transformer
, wykonaj te czynności:
- Dodaj Transformer Media3 jako zależność w projekcie.
- Utwórz obiekt
EditedMediaItem
reprezentujący media do przetworzenia i zmiany, które mają być do nich zastosowane. - Utwórz
Transformer
z opisem wymaganych danych wyjściowych oraz odbiornikiem zdarzeń zakończenia i błędów. - 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ę. - 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.