Adicionar controles de mídia ao app

Um app que reproduz mídia exige componentes da interface do usuário para exibir mídia e controlar a reprodução. A biblioteca Media3 inclui um módulo de IU que contém diversos componentes de IU. Para depender do módulo de interface, adicione o seguinte dependência:

Kotlin

implementation("androidx.media3:media3-ui:1.4.1")

Groovy

implementation "androidx.media3:media3-ui:1.4.1"

O componente mais importante é PlayerView, uma visualização para reproduções de mídia. O PlayerView exibe vídeos, imagens, legendas e capa do álbum durante a reprodução, e os controles de mídia.

O PlayerView tem um método setPlayer para anexar e remover (por passando null) instâncias do player.

PlayerView

O PlayerView pode ser usado para reproduções de vídeo, imagem e áudio. Ele renderiza vídeo e legendas no caso de reprodução de vídeo, bitmaps para reprodução de imagens e pode exibir artes incluídas como metadados em arquivos de áudio. Você pode incluí-lo nos arquivos de layout como qualquer outro componente de IU. Por exemplo, uma PlayerView podem ser incluídas com o seguinte XML:

<androidx.media3.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing"
    app:show_shuffle_button="true"/>

O snippet acima ilustra que PlayerView fornece várias atributos. Esses atributos podem ser usados para personalizar o comportamento da visualização, como e sua aparência. A maioria desses atributos tem setter correspondente , que podem ser usados para personalizar a visualização no tempo de execução. A O Javadoc PlayerView lista esses atributos e métodos setter em mais detalhes.

Depois que a visualização é declarada no arquivo de layout, ela pode ser consultada no Método onCreate da atividade:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView = findViewById(R.id.player_view)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // ...
  playerView = findViewById(R.id.player_view);
}

Quando um player for inicializado, ele poderá ser anexado à visualização chamando setPlayer:

Kotlin

// Instantiate the player.
val player = ExoPlayer.Builder(context).build()
// Attach player to the view.
playerView.player = player
// Set the media item to be played.
player.setMediaItem(mediaItem)
// Prepare the player.
player.prepare()

Java

// Instantiate the player.
player = new ExoPlayer.Builder(context).build();
// Attach player to the view.
playerView.setPlayer(player);
// Set the media item to be played.
player.setMediaItem(mediaItem);
// Prepare the player.
player.prepare();

Escolha um tipo de plataforma

O atributo surface_type de PlayerView permite definir o tipo de plataforma usada para reprodução de vídeo. Além dos valores spherical_gl_surface_view (que é um valor especial para reprodução de vídeo esférico) e video_decoder_gl_surface_view (para renderização de vídeo usando extensão) renderizadores), os valores permitidos são surface_view, texture_view e none. Se a visualização é apenas para reprodução de áudio, none deve ser usada para evitar ter que criar uma superfície, porque isso pode sair caro.

Se a visualização for para reprodução de vídeo normal, então surface_view ou texture_view deve ser usado. O SurfaceView tem vários benefícios em relação ao TextureView para reprodução de vídeo:

  • Energia significativamente menor e consumo em vários dispositivos.
  • Tempo de renderização de frames mais preciso, resultando em uma reprodução de vídeo mais suave.
  • Suporte a saída de vídeo HDR com maior qualidade em dispositivos compatíveis.
  • Suporte para saída segura ao reproduzir conteúdo protegido por DRM.
  • A capacidade de renderizar conteúdo de vídeo em resolução máxima da tela no Dispositivos Android TV que aprimoram a camada de interface.

Portanto, dê preferência a SurfaceView em vez de TextureView sempre que possível. TextureView só será usado se SurfaceView não atender às suas necessidades. Um exemplo é quando animações suaves ou rolagem da superfície do vídeo são necessárias anteriores ao Android 7.0 (API de nível 24), conforme descrito nas notas a seguir. Para Neste caso, é preferível usar TextureView somente quando SDK_INT for menor. que a 24 (Android 7.0) e SurfaceView de outra forma.

Navegação com botão direcional no Android TV

O controle remoto do Android TV tem um botão direcional que envia comandos que chegar como evento principal a dispatchKeyEvent(KeyEvent) dos seus Activity. Esses precisam ser delegadas à visualização do player:

Kotlin

override fun dispatchKeyEvent(event: KeyEvent?): Boolean{
  return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event)
}

Java

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}

Solicitar o foco para a visualização do player é importante para navegar pela reprodução controles e pular anúncios. Solicite o foco em onCreate do Activity:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView.requestFocus()
  // ...
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    playerView.requestFocus();
    // ...
}

Se você estiver usando o Compose no Android TV, será necessário tornar AndroidView focalizável e delegue o evento transmitindo o parâmetro modificador para o objeto AndroidView de acordo:

AndroidView(
  modifier = modifier
    .focusable()
    .onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
  factory = { playerView }
)

Substituir drawables

O app PlayerView usa PlayerControlView para mostrar a reprodução. controles e barra de progresso. Os drawables usados por PlayerControlView podem ser substituídos por drawables com os mesmos nomes definidos no aplicativo. Consulte o Javadoc PlayerControlView para uma lista de drawables de controle que podem ser substituídas.

Mais personalização

Quando a personalização além da descrita acima for necessária, esperamos que o app desenvolvedores implementam os próprios componentes de IU em vez de usar os pelo módulo de interface do Media3.