Transformacje

Transkoduj między formatami

Możesz określić wyjściowe formaty audio i wideo, które chcesz tworzyć podczas tworzenia Transformera. Na przykład ten kod pokazuje, jak skonfigurować Transformer tak, by zwracał obraz 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 nośnika wejściowego pasuje do konfiguracji audio lub wideo, Transformer automatycznie przełącza się na transmuksowanie, czyli kopiuj skompresowane próbki 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 film, używając parametru 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ąć dowolne multimedia poza określonymi sygnaturami czasowymi rozpoczęcia i zakończenia, ustawiając konfigurację przycinania na wejściowym elemencie multimedialnym. Aby na przykład utworzyć klip zawierający tylko multimedia o długości od 10 do 20 sekund:

Kotlin

val inputMediaItem = MediaItem.Builder()
    .setUri(uri)
    .setClippingConfiguration(
        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();

Optymalizacja wersji

Aby skrócić opóźnienie wynikające z przycięcia początku filmu, włącz optymalizację przycinania.

Kotlin

Transformer.Builder(context)
    .experimentalSetTrimOptimizationEnabled(true)
    .build()

Java

new Transformer.Builder(context)
    .experimentalSetTrimOptimizationEnabled(true)
    .build();

To przyspiesza eksport, dekodując i ponownie kodując jak najmniejszą część filmu, a następnie łącząc ponownie zakodowane dane z resztą oryginalnego filmu. Optymalizacja opiera się na możliwości połączenia części pliku wejściowego z nowo zakodowanymi danymi wyjściowymi, co oznacza, że format wyjściowy kodera i format wejściowy muszą być zgodne. Jeśli np. plik został pierwotnie wyprodukowany na urządzeniu z inną implementacją kodera, prawdopodobnie nie będzie można zastosować optymalizacji. Aby optymalizacja się udała, koder przekazany Transformerowi przez EncoderFactory musi mieć poziom i profil zgodny z formatem wejściowym.

Optymalizacja działa wyłącznie z wejściem MP4 z pojedynczym zasobem, bez efektów z wyjątkiem obróć elementów i obróty podzielnych co 90 stopni. Jeśli optymalizacja się nie powiedzie, Transformer automatycznie przełączy się na normalny eksport i pokaże wynik optymalizacji w ExportResult.OptimizationResult.

Sprawdzamy tę funkcję i spodziewamy się, że w nadchodzącej wersji nie będzie ona funkcją eksperymentalną.

Edytowanie filmu

EditedMediaItems zawiera listy procesorów audio i efektów wideo, które możesz zastosować w określonej kolejności. Zawiera ona implementacje efektów wideo przeznaczone do typowych przypadków użycia. Możesz też utworzyć efekty niestandardowe i przekazać je podczas tworzenia edytowanych elementów multimedialnych.

Można przeskalować multimedia, co może pomóc zaoszczędzić na zasobach przetwarzania lub przepustowości w przypadku danych wejściowych o bardzo wysokiej rozdzielczości, takich jak filmy 4K lub 8K. Aby na przykład skalować obraz proporcjonalnie 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żna 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();

Możesz skonfigurować rotację 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, które można zastosować. Wewnętrznie platforma efektów Transformer konwertuje listę efektów wideo na sekwencję programów do cieniowania GL, które są stosowane w określonej kolejności. 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 przekształceń macierzy, co zwiększa wydajność i jakość.

Efekty wideo są też obsługiwane w podglądzie w narzędziu ExoPlayer za pomocą ExoPlayer.setVideoEffects.

Aplikacja demonstracyjna zawiera przykłady niestandardowych efektów wideo.

Zmiany dźwięku

Efekty dźwiękowe są implementowane przez zastosowanie sekwencji instancji AudioProcessor do nieprzetworzonego dźwięku (PCM). ExoPlayer obsługuje przesyłanie procesorów audio do DefaultAudioSink.Builder, co umożliwia podgląd zmian dźwięku.