Jetpack Media3 Transformer umożliwia edytowanie, konwertowanie i eksportowanie zasobów multimedialnych na Androidzie. Na tej stronie dowiesz się, jak skonfigurować podstawowe przekształcenia:
- Transkodowanie i transmuksowanie: konwertuj formaty audio i wideo lub pomiń ponowne kodowanie przez kopiowanie próbek kontenera (transmuksowanie).
- Usuwanie ścieżek: usuwaj ścieżki audio lub wideo z multimediów.
- Przycinanie i optymalizacja: przycinaj multimedia według sygnatury czasowej, korzystając z opcji szybszego eksportu za pomocą list edycji MP4 i optymalizacji przycinania.
- Efekty wideo: skaluj, obracaj lub stosuj niestandardowe efekty cieniowania OpenGL, które można też wyświetlać w ExoPlayer.
- Obraz wejściowy: przekształcaj statyczne obrazy w klipy wideo o niestandardowym czasie trwania i liczbie klatek na sekundę.
- Przetwarzanie dźwięku: łącz instancje
AudioProcessor, aby modyfikować surowy dźwięk.
Transkodowanie między formatami
Podczas tworzenia Transformer możesz określić formaty wyjściowe audio i wideo. Na przykład ten kod pokazuje, jak skonfigurować Transformer, aby generował wideo w formacie H.264/AVC i dźwięk w formacie AAC:
Kotlin
Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
Java
new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
Jeśli format multimediów wejściowych jest zgodny z konfiguracjami audio lub wideo, Transformer automatycznie przełącza się na transmuksowanie, czyli kopiowanie skompresowanych próbek z kontenera wejściowego do kontenera wyjściowego bez modyfikacji. Pozwala to uniknąć kosztów obliczeniowych i potencjalnej utraty jakości związanej z dekodowaniem i ponownym kodowaniem w tym samym formacie.
Usuwanie dźwięku lub wideo
Usuń dźwięk lub wideo za pomocą EditedMediaItem.Builder, na przykład:
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Przycinanie klipu
Możesz usunąć wszystkie multimedia poza określonymi sygnaturami czasowymi początku i końca, ustawiając konfigurację przycinania w elemencie multimediów wejściowych. Aby na przykład utworzyć klip zawierający tylko multimedia między 10 a 20 sekundą:
Kotlin
val inputMediaItem = MediaItem.Builder() .setUri(uri) .setClippingConfiguration( MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build() ) .build()
Java
MediaItem inputMediaItem = new MediaItem.Builder() .setUri(uri) .setClippingConfiguration( new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build()) .build();
Listy edycji MP4
Aby przyspieszyć przycinanie, Transformer obsługuje listy edycji MP4, co umożliwia bardziej wydajne edycje „tylko przycinania” bez pełnego ponownego transkodowania wideo. Ta metoda wykorzystuje istniejące zakodowane próbki i „reklamę przed filmem” na liście edycji, która instruuje odtwarzacz, aby rozpoczął odtwarzanie w określonym punkcie, skutecznie pomijając niechciany segment początkowy.
Aby znacznie przyspieszyć edycje „tylko przycinania”, wywołaj experimentalSetMp4EditListTrimEnabled(true).
Kotlin
Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()
Java
new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
Optymalizowanie przycinania
Aby zmniejszyć opóźnienie przycinania początku filmu, włącz optymalizację przycinania.
Kotlin
Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build()
Java
new Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build();
Przyspiesza to eksportowanie przez dekodowanie i ponowne kodowanie jak najmniejszej części filmu, a następnie łączenie ponownie zakodowanych danych z resztą oryginalnego filmu. Optymalizacja polega na możliwości łączenia części pliku wejściowego z nowo zakodowanym plikiem wyjściowym, co oznacza, że format wyjściowy kodera i format wejściowy muszą być zgodne. Jeśli na przykład plik został pierwotnie utworzony na urządzeniu z inną implementacją kodera, prawdopodobnie nie będzie można zastosować optymalizacji.
Aby optymalizacja się powiodła, koder dostarczony do Transformer za pomocą EncoderFactory musi mieć poziom i profil zgodne z formatem wejściowym.
Ta optymalizacja działa tylko w przypadku danych wejściowych MP4 z jednym zasobem bez efektów, z wyjątkiem efektów wideo bez operacji i obrotów podzielnych przez 90 stopni. Jeśli optymalizacja się nie powiedzie, Transformer automatycznie przełączy się na normalny eksport i zgłosi wynik optymalizacji w ExportResult.OptimizationResult.
Sprawdzamy tę funkcję i oczekujemy, że w przyszłej wersji przestanie być eksperymentalna.
Edycje wideo
EditedMediaItems mają listy procesorów audio i efektów wideo, które należy zastosować w odpowiedniej kolejności. Biblioteka zawiera implementacje efektów wideo do typowych zastosowań. Możesz też napisać własne efekty i przekazać je podczas tworzenia edytowanych elementów multimedialnych.
Możesz zmienić rozmiar multimediów, co może być przydatne, aby oszczędzać zasoby przetwarzania lub przepustowość podczas pracy z danymi wejściowymi o bardzo wysokiej rozdzielczości, takimi jak filmy w rozdzielczości 4K lub 8K. Aby na przykład proporcjonalnie przeskalować do wysokości 480 pikseli:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf(Presentation.createForHeight(480)), ) ) .build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480)))) .build();
Możesz też skalować według danego współczynnika, np. aby zmniejszyć rozmiar o połowę:
Kotlin
val editedMediaItem = EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build() ), ) ) .build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()))) .build();
W ten sam sposób możesz skonfigurować obrót:
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf( ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build() ), ) ) .build()
Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( new Effects( /* audioProcessors= */ ImmutableList.of(), /* videoEffects= */ ImmutableList.of( new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()))) .build();
Niestandardowe efekty wideo
Konstruktor Effects akceptuje listę efektów audio i wideo do zastosowania.
Wewnętrznie framework efektów Transformer przekształca listę efektów wideo w sekwencję programów cieniowania GL, które są stosowane w odpowiedniej kolejności. W niektórych przypadkach framework efektów może zastosować kilka efektów za pomocą jednego programu cieniowania.
Na przykład jeden program cieniowania może zastosować kilka kolejnych przekształceń macierzowych, co zwiększa wydajność i jakość.
Efekty wideo są też obsługiwane w przypadku podglądu w ExoPlayer za pomocą ExoPlayer.setVideoEffects. Przykład użycia tego interfejsu API znajdziesz w
aplikacji demonstracyjnej efektów.
Aplikacja demonstracyjna zawiera przykłady niestandardowych efektów wideo.
Obraz wejściowy
Transformer obsługuje obrazy wejściowe, traktując je jako statyczne klipy wideo. Aby skonfigurować obraz jako źródło sygnału, wykonaj następujące czynności:
Utwórz
MediaItemza pomocąMediaItem.Builder. Określ czas wyświetlania obrazu w filmie wyjściowym, wywołującsetImageDurationMs.Utwórz
EditedMediaItemotaczającyMediaItem. Określ docelową liczbę klatek na sekundę dla wygenerowanego strumienia wideo za pomocąEditedMediaItem.Builder#setFrameRate.
Ten przykład pokazuje, jak skonfigurować obraz wejściowy, aby wygenerować 5-sekundowy film z 30 klatkami na sekundę:
Kotlin
val imageMediaItem = MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build() val editedImageItem = EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build()
Java
MediaItem imageMediaItem = new MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build(); new EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build();
Edycje audio
Efekty dźwiękowe są implementowane przez zastosowanie sekwencji instancji AudioProcessor do surowego dźwięku (PCM). ExoPlayer obsługuje przekazywanie procesorów audio do DefaultAudioSink.Builder, co umożliwia wyświetlanie podglądu edycji audio.