A introdução ao Transformer
consiste nas seguintes etapas:
- Adicione o Media3 Transformer como uma dependência no seu projeto.
- Crie um
EditedMediaItem
que represente a mídia a ser processada e as edições a serem aplicadas a ela. - Crie um
Transformer
, descrevendo a saída necessária e um listener para eventos de conclusão e de erro. - Inicie a operação de exportação, transmitindo o
EditedMediaItem
para editar e um caminho de saída. Durante a exportação, é possível consultar o progresso atual ou cancelar a operação. - Quando a exportação for concluída, processe a saída conforme necessário. Por exemplo, você pode compartilhar a saída para outro app ou fazer upload dela para um servidor.
Leia mais sobre essas etapas e consulte TransformerActivity
no
app de demonstração
do transformador para conferir um
exemplo completo.
Adicionar o Media3 Transformer como uma dependência
A maneira mais fácil de começar a usar o Transformer é adicionar dependências do Gradle
à biblioteca no arquivo build.gradle
do módulo do app:
Kotlin
implementation("androidx.media3:media3-transformer:1.4.1") implementation("androidx.media3:media3-effect:1.4.1") implementation("androidx.media3:media3-common:1.4.1")
Groovy
implementation "androidx.media3:media3-transformer:1.4.1" implementation "androidx.media3:media3-effect:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
em que 1.4.1 é a versão que você prefere. A versão mais recente pode ser encontrada consultando as notas da versão.
Mais informações sobre os módulos de biblioteca disponíveis podem ser encontradas na página Google Maven AndroidX Media3.
Ativar o suporte a Java 8
Se ainda não estiver ativado, ative o suporte ao Java 8 em todos os arquivos build.gradle
que dependem do Transformer adicionando o seguinte à seção
android
:
compileOptions {
targetCompatibility JavaVersion.VERSION_1_8
}
Iniciar uma transformação
Confira um exemplo de como criar um EditedMediaItem
para remover o áudio de um arquivo
de entrada e, em seguida, criar e configurar uma instância Transformer
para exportar
vídeo H.265/HEVC, enviando o resultado para outputPath
.
Kotlin
val inputMediaItem = MediaItem.fromUri("path_to_input_file") val editedMediaItem = EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build() val transformer = Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .addListener(transformerListener) .build() transformer.start(editedMediaItem, outputPath)
Java
MediaItem inputMediaItem = MediaItem.fromUri("path_to_input_file"); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build(); Transformer transformer = new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .addListener(transformerListener) .build(); transformer.start(editedMediaItem, outputPath);
Para mais informações sobre itens de mídia, consulte a página de itens de mídia do ExoPlayer. A entrada pode ser um stream progressivo ou adaptativo, mas a saída é sempre um stream progressivo. Para entradas adaptáveis, as faixas de maior resolução são sempre selecionadas para a transformação. A entrada pode ser de qualquer formato de contêiner compatível com o ExoPlayer, mas a saída é sempre um arquivo MP4.
É possível executar várias operações de exportação sequencialmente na mesma
instância Transformer
, mas não é possível fazer exportações simultâneas com a mesma
instância.
Observação sobre linhas de execução
As instâncias do transformador precisam ser acessadas em uma única linha de execução do aplicativo, e os métodos do listener são chamados na mesma linha de execução. Na maioria dos casos, a linha de execução do aplicativo pode ser apenas a linha de execução principal do aplicativo. Internamente, o Transformer trabalha em segundo plano e publica as chamadas para métodos de listener na linha de execução do aplicativo.
Ouvir eventos
O método start
é assíncrono. Ele retorna imediatamente, e o app é
notificado dos eventos pelo listener transmitido ao builder Transformer
.
Kotlin
val transformerListener: Transformer.Listener = object : Transformer.Listener { override fun onCompleted(composition: Composition, result: ExportResult) { playOutput() } override fun onError(composition: Composition, result: ExportResult, exception: ExportException) { displayError(exception) } }
Java
Transformer.Listener transformerListener = new Transformer.Listener() { @Override public void onCompleted(Composition composition, ExportResult result) { playOutput(); } @Override public void onError(Composition composition, ExportResult result, ExportException exception) { displayError(exception); } };
ExportResult
inclui informações sobre o arquivo de saída, incluindo o tamanho
e as taxas de bits médias de áudio e vídeo, conforme aplicável.
Receber atualizações de progresso
Chame Transformer.getProgress
para consultar o progresso atual de uma
transformação. O valor retornado indica o estado do progresso. Se o estado
de progresso for PROGRESS_STATE_AVAILABLE
, o ProgressHolder
fornecido será
atualizado com a porcentagem de progresso atual. O exemplo a seguir mostra como
consultar periodicamente o progresso de uma transformação, em que o
método updateProgressInUi
pode ser implementado para atualizar uma barra de progresso.
Kotlin
transformer.start(inputMediaItem, outputPath) val progressHolder = ProgressHolder() mainHandler.post( object : Runnable { override fun run() { val progressState: @ProgressState Int = transformer.getProgress(progressHolder) updateProgressInUi(progressState, progressHolder) if (progressState != Transformer.PROGRESS_STATE_NOT_STARTED) { mainHandler.postDelayed(/* r= */this, /* delayMillis= */500) } } } )
Java
transformer.start(inputMediaItem, outputPath); ProgressHolder progressHolder = new ProgressHolder(); mainHandler.post( new Runnable() { @Override public void run() { @Transformer.ProgressState int progressState = transformer.getProgress(progressHolder); updateProgressInUi(progressState, progressHolder); if (progressState != PROGRESS_STATE_NOT_STARTED) { mainHandler.postDelayed(/* r= */ this, /* delayMillis= */ 500); } } });
Cancelar uma transformação
Se o usuário optar por sair de um fluxo de exportação, cancele a operação de exportação
com Transformer.cancel
. Recursos como codecs de vídeo de hardware são limitados,
especialmente em dispositivos de baixo custo. Portanto, é importante fazer isso para liberar
recursos se a saída não for necessária.