Trasformazioni

Transcodifica tra formati

Puoi specificare i formati audio e video di output che vuoi produrre quando crei Transformer. Ad esempio, il seguente codice mostra come configurare Transformer per generare video H.264/AVC e audio 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();

Se il formato multimediale di input corrisponde già alle configurazioni per l'audio o il video, Transformer passa automaticamente al transmuxing, ovvero alla copia dei campioni compressi dal contenitore di input a quello di output senza modifiche. In questo modo si evitano i costi di calcolo e la potenziale perdita di qualità della decodifica e della ricodifica nello stesso formato.

Rimuovere audio o video

Rimuovi audio o video utilizzando EditedMediaItem.Builder, ad esempio:

Kotlin

EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()

Java

new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();

Tagliare un clip

Puoi rimuovere qualsiasi elemento multimediale al di fuori dei timestamp di inizio e fine specificati impostando la configurazione di ritaglio nell'elemento multimediale di input. Ad esempio, per produrre un clip contenente solo i contenuti multimediali tra 10 e 20 secondi:

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();

Elenchi di modifica MP4

Per un taglio più rapido, Transformer supporta gli elenchi di modifica MP4, consentendo modifiche "solo taglio" più efficienti senza la ricodifica completa del video. Questo metodo utilizza campioni codificati esistenti e un "pre-roll" all'interno dell'elenco di modifica, che indica al player di iniziare la riproduzione in un punto specifico, saltando di fatto il segmento iniziale indesiderato.

Per apportare modifiche solo al taglio in modo molto più rapido, chiama experimentalSetMp4EditListTrimEnabled(true).

Kotlin

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

Java

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

È importante notare che non tutti i lettori multimediali supportano una posizione "pre-roll". Ciò significa che quando viene utilizzato un player di questo tipo, la riproduzione del file inizierà dall'inizio assoluto del campione codificato, indipendentemente dalle informazioni dell'elenco di modifica che potrebbero specificare un punto di partenza diverso.

Ottimizzazione dei tagli

Per ridurre la latenza del taglio dell'inizio di un video, abilita l'ottimizzazione del taglio.

Kotlin

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

Java

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

In questo modo, l'esportazione viene velocizzata decodificando e ricodificando la minor parte possibile del video, per poi unire i dati ricodificati con il resto del video originale. L'ottimizzazione si basa sulla possibilità di unire parte del file di input con l'output appena codificato, il che significa che il formato di output del codificatore e il formato di input devono essere compatibili. Ad esempio, se il file è stato originariamente prodotto su un dispositivo con un'implementazione dell'encoder diversa, è probabile che non sia possibile applicare l'ottimizzazione. Affinché l'ottimizzazione vada a buon fine, il codificatore fornito a Transformer tramite EncoderFactory deve avere un livello e un profilo compatibili con il formato di input.

Questa ottimizzazione funziona solo con input MP4 a un solo asset senza effetti, ad eccezione di effetti video e rotazioni divisibili per 90 gradi. Se l'ottimizzazione non va a buon fine, Transformer torna automaticamente all'esportazione normale e segnala il risultato dell'ottimizzazione in ExportResult.OptimizationResult.

Stiamo convalidando questa funzionalità e prevediamo che diventerà non sperimentale in una release successiva.

Modifiche ai video

EditedMediaItems hanno elenchi di processori audio ed effetti video da applicare in ordine. La libreria include implementazioni di effetti video per casi d'uso comuni oppure puoi scrivere effetti personalizzati e passarli durante la creazione di elementi multimediali modificati.

Puoi ridimensionare i contenuti multimediali, il che può essere utile per risparmiare risorse di elaborazione o larghezza di banda quando si ha a che fare con input ad altissima risoluzione, come video in 4K o 8K. Ad esempio, per scalare proporzionalmente a 480 pixel di altezza:

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();

In alternativa, puoi scalare in base a un determinato fattore, ad esempio per dimezzare le dimensioni:

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();

Puoi configurare la rotazione nello stesso modo:

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();

Effetti video personalizzati

Il costruttore Effects accetta un elenco di effetti audio e video da applicare. A livello interno, il framework degli effetti di Transformer converte l'elenco degli effetti video in una sequenza di programmi shader GL che vengono applicati in ordine. In alcuni casi, il framework degli effetti è in grado di applicare più effetti con un programma shader. Ad esempio, un programma shader può applicare più trasformazioni di matrici consecutive, il che migliora l'efficienza e la qualità.

Gli effetti video sono supportati anche per l'anteprima in ExoPlayer, utilizzando ExoPlayer.setVideoEffects. Per un esempio di come utilizzare questa API, consulta l'app demo degli effetti.

L'app demo include esempi di effetti video personalizzati.

Modifiche audio

Gli effetti audio vengono implementati applicando una sequenza di istanze AudioProcessor all'audio grezzo (PCM). ExoPlayer supporta il passaggio dei processori audio a DefaultAudioSink.Builder, il che consente di visualizzare l'anteprima delle modifiche audio.