Notícias sobre produtos

Media3 1.9.0: novidades

Leitura de 6 minutos
Kristina Simakova
Gerente de engenharia

O Media3 1.9.0 já está disponível. Além das correções de bugs e melhorias de desempenho comuns, a versão mais recente também contém quatro módulos novos ou amplamente reescritos:

  • media3-inspector: extrair metadados e frames fora da reprodução
  • media3-ui-compose-material3: crie uma interface básica de mídia do Material3 Compose em apenas algumas etapas.
  • media3-cast: lida automaticamente com as transições entre o Cast e as reproduções locais.
  • media3-decoder-av1: reprodução consistente de AV1 com o decodificador de extensão reescrito com base na biblioteca dav1d.

Também adicionamos melhorias de gerenciamento de memória e cache ao PreloadManager e oferecemos várias novas simplificações de ExoPlayer, Transformer e MediaSession

Esta versão também oferece o primeiro acesso experimental ao CompositionPlayer para visualizar edições de mídia.  


Leia mais para saber mais e, como sempre, confira as notas da versão completas para ter uma visão geral das mudanças nesta versão.

Extrair metadados e frames fora da reprodução

Há muitos casos em que você quer inspecionar a mídia sem iniciar a reprodução. Por exemplo, é possível detectar quais formatos ele contém ou qual é a duração, ou recuperar miniaturas.

O novo módulo media3-inspector combina todas as utilidades para inspecionar mídia sem reprodução em um só lugar:

  • MetadataRetriever para ler duração, formato e metadados estáticos de um MediaItem.
  • FrameExtractor para receber frames ou miniaturas de um item.
  • MediaExtractorCompat como substituto direto da classe MediaExtractor da plataforma Android para receber informações detalhadas sobre amostras no arquivo.

MetadataRetriever e FrameExtractor seguem um padrão AutoCloseable simples. Confira nossas novas páginas de guia para mais detalhes.

  suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Crie uma interface do usuário de mídia básica do Material3 Compose em apenas algumas etapas

Em versões anteriores, começamos a fornecer código de conector entre elementos da interface do Compose e sua instância do Player. Com o Media3 1.9.0, adicionamos um novo módulo media3-ui-compose-material3 com botões e elementos de conteúdo do Material3 totalmente estilizados. Eles permitem criar uma interface de mídia em apenas algumas etapas, oferecendo toda a flexibilidade para personalizar o estilo. Se você preferir criar seu próprio estilo de interface, use os elementos básicos que cuidam de toda a lógica de atualização e conexão. Assim, você só precisa se concentrar no design do elemento da interface. Confira nossas páginas de guia estendidas para os módulos da interface do Compose.

Também estamos trabalhando em mais componentes do Compose, como uma barra de busca pré-criada, uma substituição completa e pronta para uso do PlayerView, além da integração de legendas e anúncios.

  @Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

Interface simples do player do Compose com elementos prontos para uso

Processar automaticamente as transições entre transmissões e reproduções locais

O CastPlayer no módulo media3-cast foi reescrito para processar automaticamente as transições entre a reprodução local (por exemplo, com ExoPlayer) e a reprodução remota do Cast.

Ao configurar seu MediaSession, basta criar um CastPlayer em torno do ExoPlayer e adicionar um MediaRouteButton à sua interface. Pronto!

  // MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Nova integração do CastPlayer no app de demonstração da sessão Media3

Reprodução consistente de AV1 com a extensão reescrita baseada em dav1d

A versão 1.9.0 contém um módulo de extensão AV1 completamente reescrito com base na biblioteca dav1d (link em inglês).

Como em todos os módulos de decodificador de extensão, observe que é necessário criar do código-fonte  para agrupar o código nativo relevante corretamente. Agrupar um decodificador oferece consistência e compatibilidade de formato em todos os dispositivos, mas como ele executa a decodificação no seu processo, é mais adequado para conteúdo confiável. 

Integrar o gerenciamento de cache e memória ao PreloadManager

Também melhoramos nosso PreloadManager. Ele já permitia pré-carregar mídia na memória fora da reprodução e depois transferir para um player quando necessário. Embora seja bastante eficiente, ainda era preciso ter cuidado para não exceder os limites de memória ao pré-carregar demais por acidente. Por isso, com o Media3 1.9.0, adicionamos dois recursos que facilitam e estabilizam muito esse processo:

  1. Suporte ao armazenamento em cache : ao definir o quanto pré-carregar, agora é possível escolher PreloadStatus.specifiedRangeCached(0, 5000) como um estado de destino para itens pré-carregados. Isso adiciona o intervalo especificado ao cache no disco em vez de carregar os dados na memória. Assim, você pode fornecer uma variedade muito maior de itens para pré-carregamento, já que os mais distantes do item atual não precisam mais ocupar a memória. Isso exige a definição de um Cache em DefaultPreloadManager.Builder.
  2. Gerenciamento automático de memória : também atualizamos nossa interface LoadControl para lidar melhor com o caso de pré-carregamento. Agora é possível definir um limite superior explícito de memória para todos os itens pré-carregados. O padrão é 144 MB, e você pode configurar o limite em DefaultLoadControl.Builder. O DefaultPreloadManager vai parar de pré-carregar automaticamente quando o limite for atingido e vai liberar a memória de itens de menor prioridade, se necessário.

Confie nos novos comportamentos padrão simplificados do ExoPlayer

Como sempre, também adicionamos muitas melhorias incrementais ao ExoPlayer. Para citar alguns:

  • Ativar e desativar o som: já tínhamos um método setVolume, mas agora adicionamos os métodos convenientes mute e unmute para restaurar facilmente o volume anterior sem precisar acompanhar você mesmo.
  • Detecção de player travado: em alguns casos raros, o player pode ficar travado em um estado de buffer ou reprodução sem progredir, por exemplo, devido a problemas de codec ou configurações incorretas. Seus usuários vão ficar irritados, mas você nunca vai ver esses problemas nas suas análises. Para deixar isso mais óbvio, o player agora informa um StuckPlayerException quando detecta um estado travado.
  • Wakelock por padrão: antes, o gerenciamento de wake lock era ativado por inclusão, o que resultava em casos extremos difíceis de encontrar em que o progresso da reprodução podia ser muito atrasado ao ser executado em segundo plano. Agora, esse recurso é de recusa. Assim, você não precisa se preocupar com ele e também pode remover todo o processamento manual de wake lock durante a reprodução.
  • Configuração simplificada para a lógica do botão de legendas descritivas: mudar TrackSelectionParameters para "ativar/desativar legendas" foi surpreendentemente difícil de fazer certo. Por isso, adicionamos uma opção booleana simples selectTextByDefault para esse caso de uso.

Simplifique suas preferências de botão de mídia no MediaSession

Até agora, definir suas preferências sobre quais botões deveriam aparecer no painel de notificações de mídia no Android Auto ou no WearOS exigia a definição de comandos e botões personalizados, mesmo que você quisesse apenas acionar um método de player padrão.

A Media3 1.9.0 tem uma nova funcionalidade para simplificar muito isso. Agora você pode definir suas preferências de botão de mídia com um comando de player padrão, sem precisar de processamento de comandos personalizados.

  session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Preferências de botões de mídia com o botão de avançar

CompositionPlayer para visualização em tempo real

A versão 1.9.0 apresenta o CompositionPlayer em uma nova anotação @ExperimentalApi. A anotação indica que ele está disponível para testes, mas ainda está em desenvolvimento. 

CompositionPlayer é um novo componente nas APIs de edição do Media3 projetado para visualização em tempo real de edições de mídia. Criado com base na interface Player do Media3, o CompositionPlayer permite que os usuários vejam as mudanças em ação antes de confirmar o processo de exportação. Ele usa o mesmo objeto Composition que você transmitiria para Transformer para exportação, simplificando o fluxo de trabalho de edição ao unificar o modelo de dados para visualização e exportação.

Recomendamos que você comece a usar o CompositionPlayer, compartilhe seu feedback e fique de olho nas próximas postagens e atualizações da documentação para mais detalhes.

InAppMuxer como um muxer padrão no Transformer

Agora, o Transformer usa o InAppMp4Muxer como o muxer padrão para gravar arquivos de contêiner de mídia. Internamente, o InAppMp4Muxer depende do módulo Muxer da Media3, oferecendo um comportamento consistente em todas as versões da API. 

Embora o Transformer não use mais o MediaMuxer da plataforma Android por padrão, ainda é possível fornecer FrameworkMuxer.Factory usando setMuxerFactory se o caso de uso exigir.

Novas APIs de ajuste de velocidade

A versão 1.9.0 simplifica as APIs de ajuste de velocidade para edição de mídia. Implementamos novos métodos diretamente em EditedMediaItem.Builder para controlar a velocidade, tornando a API mais intuitiva. Agora é possível mudar a velocidade de um clipe chamando setSpeed(SpeedProvider provider) no EditedMediaItem.Builder:

  val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

Essa nova abordagem substitui o método anterior de usar Effects#createExperimentalSpeedChangingEffects(), que foi descontinuado e será removido em uma versão futura.

Introdução aos tipos de faixa para EditedMediaItemSequence 

Na versão 1.9.0, EditedMediaItemSequence exige a especificação dos tipos de faixa de saída desejados durante a criação da sequência. Essa mudança garante que o processamento de faixas seja mais explícito e robusto em toda a composição. 

Isso é feito com um novo construtor EditedMediaItemSequence.Builder que aceita um conjunto de tipos de faixa (por exemplo, C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

Para simplificar a criação, adicionamos novos métodos estáticos de conveniência:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Recomendamos que você migre para o novo construtor ou os métodos de conveniência para definições de sequência mais claras e confiáveis.

Exemplo de criação de uma sequência somente de vídeo:

  EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Entre em contato pelo Rastreador de problemas do Media3 se encontrar bugs ou tiver dúvidas ou solicitações de recursos. Esperamos você!

Escrito por:

Continuar lendo