Transcodificar entre formatos
É possível especificar os formatos de áudio e vídeo de saída que você quer produzir ao criar o Transformer. Por exemplo, o código a seguir mostra como configurar o Transformer para gerar vídeo H.264/AVC e áudio 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 o formato de mídia de entrada já corresponder às configurações de áudio ou vídeo, o Transformer vai mudar automaticamente para transmuxing, ou seja, copiar as amostras compactadas do contêiner de entrada para o contêiner de saída sem modificação. Isso evita o custo computacional e a possível perda de qualidade da decodificação e da recodificação no mesmo formato.
Remover áudio ou vídeo
Remova áudio ou vídeo usando EditedMediaItem.Builder
, por exemplo:
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Cortar um clipe
É possível remover qualquer mídia fora dos carimbos de data/hora de início e fim especificados definindo a configuração de corte no item de mídia de entrada. Por exemplo, para gerar um clipe que contenha apenas a mídia entre 10 e 20 segundos:
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();
Listas de edição MP4
Para um corte mais rápido, o Transformer é compatível com listas de edição MP4, permitindo edições mais eficientes de "somente corte" sem a retranscodificação completa do vídeo. Esse método usa amostras codificadas e um "pré-roll" na lista de edições, que instrui o player a iniciar a reprodução em um ponto específico, pulando o segmento inicial indesejado.
Para fazer edições de corte muito mais rápido, chame
experimentalSetMp4EditListTrimEnabled(true)
.
Kotlin
Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build();
É importante observar que nem todos os players de mídia são compatíveis com uma posição de "anúncio precedente". Isso significa que, quando um player desse tipo é usado, o arquivo começa a ser reproduzido desde o início absoluto da amostra codificada, independente de qualquer informação da lista de edição que possa especificar um ponto de partida diferente.
Como otimizar cortes
Para reduzir a latência do corte do início de um vídeo, ative a otimização de corte.
Kotlin
Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build();
Isso acelera a exportação porque decodifica e recodifica o mínimo possível do vídeo e depois junta os dados recodificados com o restante do vídeo original. A otimização depende da capacidade de juntar parte do arquivo de entrada
com a saída recém-codificada, o que significa que o formato de saída do codificador e o
formato de entrada precisam ser compatíveis. Por exemplo, se o arquivo foi produzido originalmente em um dispositivo com uma implementação de codificador diferente, provavelmente não será possível aplicar a otimização.
Para que a otimização seja bem-sucedida, o codificador fornecido ao Transformer via
EncoderFactory
precisa ter um nível e um perfil compatíveis com o formato de entrada.
Essa otimização só funciona com entradas MP4 de um único recurso sem efeitos, exceto efeitos de vídeo sem operação e rotações divisíveis por 90 graus. Se a otimização falhar, o Transformer vai voltar automaticamente à exportação normal e informar o resultado da otimização em ExportResult.OptimizationResult
.
Estamos validando essa funcionalidade e esperamos que ela deixe de ser experimental em uma versão futura.
Edições de vídeo
EditedMediaItems
tem listas de processadores de áudio e efeitos de vídeo para aplicar em
ordem. A biblioteca inclui implementações de efeitos de vídeo para casos de uso comuns. Você também pode escrever efeitos personalizados e transmiti-los ao criar itens de mídia editados.
É possível redimensionar a mídia, o que pode ser útil para economizar recursos de processamento ou largura de banda ao lidar com entradas de resolução muito alta, como vídeos em 4K ou 8K. Por exemplo, para dimensionar proporcionalmente a 480 pixels de altura:
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();
Outra opção é dimensionar por um determinado fator, por exemplo, para reduzir o tamanho pela metade:
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();
É possível configurar a rotação da mesma forma:
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();
Efeitos de vídeo personalizados
O construtor Effects
aceita uma lista de efeitos de áudio e vídeo para aplicar.
Internamente, a estrutura de efeitos do Transformer converte a lista de efeitos de vídeo
em uma sequência de programas de shader GL que são aplicados em ordem. Em alguns casos,
a estrutura de efeitos consegue aplicar vários efeitos com um programa de sombreador.
Por exemplo, um programa de shader pode aplicar várias transformações de matriz consecutivas, o que melhora a eficiência e a qualidade.
Os efeitos de vídeo também são compatíveis com a prévia no ExoPlayer usando
ExoPlayer.setVideoEffects
. Para um exemplo de como usar essa API, confira
o app de demonstração de efeitos.
O app de demonstração inclui exemplos de efeitos de vídeo personalizados.
Edições de áudio
Os efeitos de áudio são implementados aplicando uma sequência de instâncias AudioProcessor
ao áudio bruto (PCM). O ExoPlayer permite transmitir processadores de áudio para o
DefaultAudioSink.Builder
, o que permite visualizar edições de áudio.