klipy, stosować efekty wideo i optymalizować eksportowanie. keywords_public: Media3, Transformer, transkodowanie, edycja wideo, przycinanie, przetwarzanie audio, multimedia na Androidzie
Transkodowanie między formatami
Podczas tworzenia transformatora możesz określić formaty wyjściowe audio i wideo, które chcesz uzyskać. Na przykład poniższy kod pokazuje, jak skonfigurować Transformer, aby generował wideo H.264/AVC i dźwięk 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 wejściowego pliku multimedialnego 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 obrazu
Usuń dźwięk lub obraz za pomocą ikony 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 znacznikami czasu rozpoczęcia i zakończenia, konfigurując przycinanie w przypadku wejściowego elementu multimedialnego. 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 pozwala na bardziej wydajne edycje „tylko przycinanie” bez pełnego przekodowywania wideo. Ta metoda wykorzystuje istniejące zakodowane próbki i „reklama przed filmem” na liście edycji, który instruuje odtwarzacz, aby rozpoczął odtwarzanie w określonym momencie, skutecznie pomijając niechciany początkowy segment.
Aby znacznie przyspieszyć edycję polegającą tylko na przycinaniu, wywołaj
experimentalSetMp4EditListTrimEnabled(true).
Kotlin
Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()
Java
new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
Optymalizacja wersji
Aby skrócić czas oczekiwania na przycięcie 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, ponieważ dekoduje i ponownie koduje jak najmniejszą część filmu, a następnie łączy ponownie zakodowane dane z resztą oryginalnego filmu. Optymalizacja polega na możliwości połą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 przekazany do modelu Transformer za pomocą parametru 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 powróci do normalnego eksportu i zwróci wynik optymalizacji w ExportResult.OptimizationResult.
Sprawdzamy tę funkcję i spodziewamy się, że w przyszłej wersji przestanie być eksperymentalna.
Zmiany w filmach
EditedMediaItems zawierają listy procesorów dźwięku i efektów wideo, które należy zastosować w odpowiedniej kolejności; Biblioteka zawiera implementacje efektów wideo w przypadku typowych zastosowań. Możesz też napisać własne efekty i przekazać je podczas tworzenia edytowanych elementów multimedialnych.
Możesz zmienić skalę multimediów, co może być przydatne, aby zaoszczędzić zasoby przetwarzania lub przepustowość w przypadku danych wejściowych o bardzo wysokiej rozdzielczości, takich jak filmy w rozdzielczości 4K lub 8K. Aby na przykład proporcjonalnie przeskalować obraz 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();
Rotację możesz skonfigurować w ten sam sposób:
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ć wiele efektów za pomocą jednego programu cieniowania.
Na przykład jeden program cieniujący może stosować wiele kolejnych przekształceń macierzowych, co zwiększa wydajność i jakość.
Efekty wideo są też obsługiwane w podglądzie w ExoPlayerze za pomocą ExoPlayer.setVideoEffects. Przykład użycia tego interfejsu API znajdziesz w aplikacji demonstracyjnej efektu.
Aplikacja w wersji demonstracyjnej zawiera przykłady niestandardowych efektów wideo.
Obraz wejściowy
Transformer obsługuje dane wejściowe w postaci obrazów, traktując je jako statyczne klipy wideo. Aby skonfigurować obraz jako źródło sygnału, wykonaj te czynności:
Utwórz
MediaItemza pomocąMediaItem.Builder. Określ czas wyświetlania obrazu w filmie wyjściowym, wywołując funkcjęsetImageDurationMs.Utwórz element
EditedMediaItem, który będzie zawierać elementMediaItem. Określ docelową liczbę klatek na sekundę dla wygenerowanego strumienia wideo za pomocąEditedMediaItem.Builder#setFrameRate.
Przykład poniżej pokazuje, jak skonfigurować dane wejściowe obrazu, aby wygenerować 5-sekundowy film z częstotliwością 30 klatek 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();
Zmiany w dźwięku
Efekty audio są implementowane przez zastosowanie sekwencji instancji AudioProcessor do surowego dźwięku (PCM). ExoPlayer obsługuje przekazywanie procesorów dźwięku do DefaultAudioSink.Builder, co umożliwia podgląd zmian w dźwięku.