Transkodowanie między formatami
Podczas tworzenia transformatora możesz określić formaty wyjściowe audio i wideo. Na przykład poniższy kod pokazuje, jak skonfigurować transformator, 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 multimediów wejściowych jest zgodny z konfiguracjami audio lub wideo, transformator 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
Aby usunąć dźwięk lub wideo, użyj 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, transformator obsługuje listy edycji MP4, co pozwala na bardziej wydajne edycje „tylko przycinanie” 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 momencie, skutecznie pomijając niechciany segment początkowy.
Aby znacznie przyspieszyć edycje „tylko przycinanie”, wywołaj experimentalSetMp4EditListTrimEnabled(true).
Kotlin
Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()
Java
new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
Optymalizacja 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, 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 wyjściem, 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 transformatora za pomocą EncoderFactory musi mieć poziom i profil zgodne z formatem wejściowym.
Ta optymalizacja działa tylko w przypadku wejściowego pliku MP4 z jednym zasobem bez efektów, z wyjątkiem efektów wideo no-op i obrotów podzielnych przez 90 stopni. Jeśli optymalizacja się nie powiedzie, transformator 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.
Zmiany w filmach
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 w typowych przypadkach użycia. Możesz też napisać własne efekty i przekazać je podczas tworzenia edytowanych elementów multimediów.
Możesz zmienić skalę multimediów, co może być przydatne, aby zaoszczędzić zasoby przetwarzania lub przepustowość podczas pracy z danymi wejściowymi o bardzo wysokiej rozdzielczości, takimi jak filmy 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 transformatora 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 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 w wersji demonstracyjnej zawiera przykłady niestandardowych efektów wideo.
Obraz wejściowy
Transformator 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 szybkoś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();
Edycja dźwięku
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 dźwięku.