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 {: #remove-audio-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 {: #trim }
Puoi rimuovere qualsiasi contenuto 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(
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();
## Elenchi di modifica MP4 {: #mp4-edit-lists }
Per un taglio più rapido, Transformer supporta gli elenchi di modifica MP4, consentendo modifiche "solo taglio" più efficienti senza la completa ricodifica 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 rendere le modifiche solo di taglio molto più veloci, 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 da eventuali informazioni dell'elenco di modifica che potrebbero specificare un punto di partenza diverso.
Attenzione: il taglio del video spesso implica la rimozione definitiva delle sezioni indesiderate. Tuttavia,
l'utilizzo degli elenchi di modifica crea un rischio per la privacy: gli utenti potrebbero condividere inconsapevolmente
informazioni sensibili "eliminate" "nascoste" dalla posizione "pre-roll".
## Ottimizzazione dei tagli {: #trim-optimization }
Per ridurre la latenza del taglio dell'inizio di un video, attiva 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, l'encoder 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 video {: #video-edits }
`EditedMediaItems` contengono 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 a risoluzione molto elevata, 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 {: #custom-video }
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][effect-demo-app].
L'[app demo](demo-application) include esempi di effetti video personalizzati.
## Input immagine {: #image-input }
Transformer supporta gli input immagine trattandoli come video clip statici. Per
configurare un'immagine come origine di input, segui questi passaggi:
* Crea un `MediaItem` utilizzando `MediaItem.Builder`. Specifica la durata
di visualizzazione dell'immagine nel video di output chiamando `setImageDurationMs`.
* Crea un `EditedMediaItem` che racchiuda `MediaItem`. Specifica il frame rate
di destinazione per lo stream video generato utilizzando
`EditedMediaItem.Builder#setFrameRate`.
Il seguente esempio mostra come configurare un input immagine per generare un video
di 5 secondi a 30 frame al secondo:
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();
EditedMediaItem editedImageItem = new EditedMediaItem.Builder(imageMediaItem)
.setFrameRate(30) // 30 frames per second
.build();
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.