Transkoduj między formatami
Możesz określić wyjściowe formaty audio i wideo, które chcesz tworzyć, Buduję Transformera. Na przykład ten kod pokazuje, jak aby skonfigurować Transformer tak, by wysyłał dźwięk H.264/AVC i dźwięk AAC:
Transformer.Builder(context)
.setVideoMimeType(MimeTypes.VIDEO_H264)
.setAudioMimeType(MimeTypes.AUDIO_AAC)
.build()
new Transformer.Builder(context)
.setVideoMimeType(MimeTypes.VIDEO_H264)
.setAudioMimeType(MimeTypes.AUDIO_AAC)
.build();
Jeśli format nośnika wejściowego jest już zgodny z konfiguracją dźwięku 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 na dekodowaniu i ponownym kodowaniu w tym samym formacie.
Usuwanie dźwięku lub obrazu
Usuń dźwięk lub film, używając parametru EditedMediaItem.Builder
, na przykład:
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Przycinanie klipu
Możesz usunąć multimedia poza określonymi sygnaturami czasowymi rozpoczęcia i zakończenia, ustawiając konfiguracji przycinania na wejściowym elemencie multimedialnym. Aby na przykład utworzyć klip zawierający wyłącznie multimedia o długości od 10 do 20 sekund:
val inputMediaItem = MediaItem.Builder()
.setUri(uri)
.setClippingConfiguration(
ClippingConfiguration.Builder()
.setStartPositionMs(10_000)
.setEndPositionMs(20_000)
.build())
.build()
MediaItem inputMediaItem =
new MediaItem.Builder()
.setUri(uri)
.setClippingConfiguration(
new MediaItem.ClippingConfiguration.Builder()
.setStartPositionMs(10_000)
.setEndPositionMs(20_000)
.build())
.build();
Optymalizowanie wersji
Aby skrócić opóźnienie wynikające z przycięcia początku filmu, włącz funkcję przycinania optymalizacji.
Transformer.Builder(context)
.experimentalSetTrimOptimizationEnabled(true)
.build()
new Transformer.Builder(context)
.experimentalSetTrimOptimizationEnabled(true)
.build();
To przyspiesza eksport, dekodując i ponownie kodując tylko fragment filmu,
a następnie połączyć ponownie zakodowane dane z resztą oryginału
film. Optymalizacja zależy od możliwości złączenia części pliku wejściowego
z nowo zakodowanym sygnałem wyjściowym, co oznacza, że format wyjściowy kodera i
format danych wejściowych musi być zgodny. Jeśli na przykład plik został pierwotnie
wygenerowane na urządzeniu z inną implementacją kodera, prawdopodobnie
że nie będzie można zastosować optymalizacji.
Aby optymalizacja się powiodła, koder został przekazany do Transformera przez
EncoderFactory
musi mieć poziom i profil zgodne z formatem danych wejściowych.
Ta optymalizacja działa tylko z wejściem MP4 z pojedynczym zasobem. Nie ma żadnych efektów
brak efektów wideo działań ani obrotów, które są podzielone co 90 stopni. Jeśli optymalizacja
nie działa, Transformer automatycznie powraca do normalnego eksportu i zgłasza
wynik optymalizacji w ExportResult.OptimizationResult
.
Sprawdzamy tę funkcję i spodziewamy się, że nie będzie ona funkcją eksperymentalną w kolejnej wersji.
Edytowanie filmu
EditedMediaItems
ma listy procesorów audio i efektów wideo, które można zastosować
zamówienie. Zawiera ona implementacje efektów wideo przeznaczone do typowych zastosowań,
Możesz też dodać efekty niestandardowe i przekazać je podczas tworzenia edytowanych multimediów
elementy(ów).
Można przeskalować multimedia, co może pomóc ograniczyć ilość przetwarzanych zasobów lub w przypadku obsługi danych wejściowych o bardzo wysokiej rozdzielczości, np. 4K lub 8K. Aby na przykład skalować obraz proporcjonalnie do wysokości 480 pikseli:
EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(Effects(
/* audioProcessors= */ listOf(),
/* videoEffects= */ listOf(Presentation.createForHeight(480))
)).build()
new EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(new Effects(
/* audioProcessors= */ ImmutableList.of(),
/* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480))))
.build();
Można też skalować według danego współczynnika, np. aby zmniejszyć rozmiar o połowę:
val editedMediaItem = EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(Effects(
/* audioProcessors= */ listOf(),
/* videoEffects= */ listOf(
ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())
)).build()
new EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(new Effects(
/* audioProcessors= */ ImmutableList.of(),
/* videoEffects= */ ImmutableList.of(
new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())))
.build();
Możesz skonfigurować rotację w ten sam sposób:
EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(Effects(
/* audioProcessors= */ listOf(),
/* videoEffects= */ listOf(
ScaleAndRotateTransformation.Builder()
.setRotationDegrees(90f)
.build())
)).build()
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, które można zastosować.
Wewnętrznie platforma efektów Transformer konwertuje listę efektów wideo
w sekwencję stosowanych po kolei programów do cieniowania GL. W niektórych przypadkach
platforma efektów może zastosować wiele efektów w ramach jednego programu do cieniowania.
Na przykład jeden program do cieniowania może stosować kilka kolejnych macierzy
transformacji, co poprawia wydajność i jakość.
Efekty wideo są również obsługiwane w podglądzie w narzędziu ExoPlayer, w którym są wykorzystywane
ExoPlayer.setVideoEffects
Aplikacja demonstracyjna zawiera przykłady niestandardowych efektów wideo.
Zmiany dźwięku
Efekty dźwiękowe są implementowane przez zastosowanie sekwencji AudioProcessor
nieprzetworzonego dźwięku (PCM). ExoPlayer obsługuje procesory audio
DefaultAudioSink.Builder
, który umożliwia wyświetlanie podglądu zmian w ścieżce dźwiękowej.