Cómo agregar controles de reproducción a tu app

Una app que reproduce contenido multimedia requiere componentes de la interfaz de usuario para mostrar contenido multimedia y controlando la reproducción. La biblioteca Media3 incluye un módulo de IU que contiene varios componentes de la interfaz de usuario. Para depender del módulo de IU, agrega lo siguiente dependencia:

Kotlin

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

Groovy

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

El componente más importante es PlayerView, una vista para las reproducciones de contenido multimedia. PlayerView muestra el video, las imágenes, los subtítulos y la imagen del álbum durante la reproducción. y los controles de reproducción.

PlayerView tiene un método setPlayer para adjuntar y desconectar (de pasando null) instancias del reproductor.

Vista del reproductor

PlayerView se puede usar para reproducciones de video, imágenes y audio. Procesa video y subtítulos para la reproducción de video, mapas de bits para la reproducción de imágenes y puede mostrar el material gráfico incluido como metadatos en los archivos de audio. Puedes incluirlo en tus archivos de diseño como cualquier otro componente de IU. Por ejemplo, un objeto PlayerView se pueden incluir con el siguiente 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"/>

En el fragmento anterior, se ilustra que PlayerView proporciona varias atributos. Estos atributos se pueden usar para personalizar el comportamiento de la vista, como así como su apariencia. La mayoría de estos atributos tienen un método set correspondiente que se pueden usar para personalizar la vista en el tiempo de ejecución. El PlayerView Javadoc enumera estos atributos y métodos set en en más detalle.

Una vez que se declara la vista en el archivo de diseño, puedes buscarla en Método onCreate de la actividad:

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);
}

Cuando se inicializa un reproductor, se puede adjuntar a la vista invocando 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();

Elige un tipo de superficie

El atributo surface_type de PlayerView te permite establecer el tipo de superficie que se usa para la reproducción de videos. Además de los valores spherical_gl_surface_view (que es un valor especial para la reproducción de video esférica) video_decoder_gl_surface_view (que se usa para renderizar videos con extensiones los procesadores), los valores permitidos son surface_view, texture_view y none. Si la vista es solo para la reproducción de audio, se debe usar none para evitar tener que crear una superficie, porque hacerlo puede ser costoso.

Si la vista es para la reproducción de video normal, entonces surface_view o texture_view. que se debe usar. SurfaceView tiene varios beneficios por sobre TextureView para reproducción de video:

  • Considerablemente menor consumo. de consumo en muchos dispositivos.
  • Latencia de fotogramas más precisa, lo que da como resultado una reproducción de video más fluida
  • Compatibilidad con salida de video HDR de mayor calidad en dispositivos compatibles.
  • Compatibilidad con salida segura cuando se reproduce contenido protegido por DRM.
  • La capacidad de renderizar contenido de video en la resolución completa de la pantalla en Dispositivos Android TV que mejoran la capa de la IU

Por lo tanto, se debe preferir SurfaceView en lugar de TextureView siempre que sea posible. Solo debes usar TextureView si SurfaceView no satisface tus necesidades. Uno Un ejemplo es cuando se requieren animaciones fluidas o desplazamiento de la superficie del video anteriores a Android 7.0 (nivel de API 24), como se describe en las siguientes notas. Para En este caso, es preferible usar TextureView solo cuando SDK_INT es menor a la 24 (Android 7.0) y, de lo contrario, SurfaceView.

Navegación con pad direccional en Android TV

El control remoto de Android TV tiene un pad direccional que envía comandos que llegar como evento clave a la(s) dispatchKeyEvent(KeyEvent) de la Activity. Estos deben delegarse a la vista de reproductor:

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 el enfoque de la vista del reproductor es importante para navegar por la reproducción controles y omitir los anuncios. Solicita el enfoque en onCreate de las 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();
    // ...
}

Si usas Compose en Android TV, debes hacer que AndroidView enfocable y delegue el evento pasando el parámetro modificador al AndroidView según corresponda:

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

Anula elementos de diseño

PlayerView usa PlayerControlView para mostrar la reproducción y la barra de progreso. Los elementos de diseño que usa PlayerControlView pueden puede ser anulada por elementos de diseño con los mismos nombres definidos en tu aplicación. Consulta el Javadoc de PlayerControlView para obtener una lista de elementos de diseño de control que se puede anular.

Mayor personalización

En caso de que se requiera una personalización más allá de la descrita anteriormente, se espera que la app los desarrolladores implementarán sus propios componentes de IU en lugar de usar los proporcionados por el módulo de IU de Media3.