Um app que reproduz mídia precisa de componentes da interface do usuário para mostrar mídia e controlar a reprodução. A biblioteca Media3 inclui um módulo de interface que contém vários componentes de interface. Para depender do módulo de interface, adicione a seguinte dependência:
implementation("androidx.media3:media3-ui:1.5.1")
implementation "androidx.media3:media3-ui:1.5.1"
O componente mais importante é PlayerView
, uma visualização para reprodução de mídia.
PlayerView
exibe vídeo, imagens, legendas e capa do álbum durante a reprodução,
bem como os controles de reprodução.
PlayerView
tem um método setPlayer()
para anexar e desconectar (transmitindo
null
) instâncias de jogadores.
PlayerView
O PlayerView
pode ser usado para reprodução 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 imagem
e pode mostrar a arte incluída como metadados em arquivos de áudio. É possível incluí-lo
nos arquivos de layout como qualquer outro componente de interface. Por exemplo, um PlayerView
pode ser incluído 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ários atributos.
Esses atributos podem ser usados para personalizar o comportamento da visualização, bem como a
aparência dela. A maioria desses atributos tem métodos setters correspondentes, que
podem ser usados para personalizar a visualização no momento de execução. A documentação de PlayerView
lista esses atributos e métodos de setter com mais detalhes.
Depois que a visualização é declarada no arquivo de layout, ela pode ser pesquisada no
método onCreate
da atividade:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... playerView = findViewById(R.id.player_view) }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... playerView = findViewById(R.id.player_view); }
Quando um player é inicializado, ele pode ser anexado à visualização chamando
setPlayer
:
// 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()
// 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();
Escolher um tipo de plataforma
O atributo surface_type
de PlayerView
permite definir o tipo de superfície
usado para a reprodução de vídeo. Além dos valores spherical_gl_surface_view
(que
é um valor especial para reprodução de vídeo esférica) e
video_decoder_gl_surface_view
(que é para renderização de vídeo usando renderizadores
de extensão), os valores permitidos são surface_view
, texture_view
e none
. Se
a visualização for apenas para reprodução de áudio, use none
para evitar a necessidade de
criar uma plataforma, porque isso pode ser caro.
Se a visualização for para reprodução de vídeo normal, use surface_view
ou texture_view
. O SurfaceView
tem vários benefícios em relação ao TextureView
para
reprodução de vídeo:
- Consumo de energia menor em muitos dispositivos.
- Tempo de frame mais preciso, resultando em uma reprodução de vídeo mais suave.
- Suporte para saída de vídeo HDR de 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 na resolução total da tela em dispositivos Android TV que aumentam a camada da interface.
Portanto, dê preferência a SurfaceView
em vez de TextureView
, sempre que possível.
O TextureView
só deve ser usado se o 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
antes do Android 7.0 (nível 24 da API), conforme descrito nas notas a seguir. Nesse
caso, é preferível usar TextureView
somente quando SDK_INT
for menor
que 24 (Android 7.0) e SurfaceView
, caso contrário.
Navegação com D-pad no Android TV
O controle remoto do Android TV tem um controle direcional que envia comandos que
chegam como evento de tecla em dispatchKeyEvent(KeyEvent)
do Activity
. Estes
precisam ser delegados para a visualização do player:
override fun dispatchKeyEvent(event: KeyEvent?): Boolean{ return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event) }
@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 pelos controles
de reprodução e pular anúncios. Considere solicitar o foco em onCreate
do
Activity
:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... playerView.requestFocus() // ... }
@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 o AndroidView
foco e delegar o evento transmitindo o parâmetro do modificador para o
AndroidView
de acordo:
AndroidView(
modifier = modifier
.focusable()
.onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
factory = { playerView }
)