Ajouter des commandes de lecture à votre application

Une application qui lit des contenus multimédias nécessite des composants d'interface utilisateur pour afficher des contenus multimédias et contrôler la lecture. La bibliothèque Media3 comprend un module d'interface utilisateur qui contient plusieurs composants d'interface utilisateur. Pour dépendre du module d'interface utilisateur, ajoutez la dépendance suivante:

Kotlin

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

Groovy

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

Le composant le plus important est PlayerView, une vue pour la lecture de contenus multimédias. PlayerView affiche la vidéo, les sous-titres et la pochette de l'album pendant la lecture, ainsi que les commandes de lecture.

PlayerView dispose d'une méthode setPlayer pour associer et dissocier (en transmettant null) des instances de joueur.

Vue du lecteur

PlayerView peut être utilisé pour la lecture de contenus vidéo et audio. Il affiche les vidéos et les sous-titres pour la lecture de vidéos, et peut afficher des illustrations incluses en tant que métadonnées dans les fichiers audio. Vous pouvez l'inclure dans vos fichiers de mise en page comme tout autre composant d'interface utilisateur. Par exemple, un PlayerView peut être inclus avec le code XML suivant:

<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"/>

L'extrait ci-dessus montre que PlayerView fournit plusieurs attributs. Ces attributs peuvent être utilisés pour personnaliser le comportement, ainsi que l'aspect général de la vue. La plupart de ces attributs ont des méthodes setter correspondantes, qui peuvent être utilisées pour personnaliser la vue au moment de l'exécution. La documentation Javadoc PlayerView répertorie ces attributs et méthodes setter plus en détail.

Une fois la vue déclarée dans le fichier de mise en page, vous pouvez la rechercher dans la méthode onCreate de l'activité:

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

Lorsqu'un lecteur a été initialisé, il peut être associé à la vue en appelant 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();

Choisir un type de surface

L'attribut surface_type de PlayerView vous permet de définir le type de surface utilisé pour la lecture de la vidéo. Outre les valeurs spherical_gl_surface_view (qui est une valeur spéciale pour la lecture vidéo sphérique) et video_decoder_gl_surface_view (pour le rendu vidéo à l'aide de moteurs de rendu d'extension), les valeurs autorisées sont surface_view, texture_view et none. Si la vue est destinée à la lecture audio uniquement, utilisez none pour éviter d'avoir à créer une surface, car cette opération peut s'avérer coûteuse.

Si l'affichage est destiné à une lecture vidéo standard, vous devez utiliser surface_view ou texture_view. SurfaceView présente de nombreux avantages par rapport à TextureView pour la lecture de vidéos:

  • Consommation d'énergie considérablement réduite sur de nombreux appareils.
  • Temps de rendu plus précis, pour une lecture vidéo plus fluide
  • Prise en charge d'une sortie vidéo HDR de meilleure qualité sur les appareils compatibles.
  • Prise en charge de la sortie sécurisée lors de la lecture de contenu protégé par DRM.
  • Possibilité d'afficher du contenu vidéo à la résolution maximale de l'écran sur les appareils Android TV qui améliorent la couche d'interface utilisateur.

Par conséquent, SurfaceView doit être privilégié par rapport à TextureView dans la mesure du possible. TextureView ne doit être utilisé que si SurfaceView ne répond pas à vos besoins. C'est par exemple le cas lorsque des animations fluides ou un défilement de la surface vidéo sont nécessaires avant Android 7.0 (niveau d'API 24), comme décrit dans les notes suivantes. Dans ce cas, il est préférable d'utiliser TextureView uniquement lorsque SDK_INT est inférieur à 24 (Android 7.0) et SurfaceView dans le cas contraire.

Navigation avec le pavé directionnel sur Android TV

La télécommande d'Android TV est dotée d'un pavé directionnel qui envoie des commandes qui arrivent en tant qu'événements clés à l'adresse dispatchKeyEvent(KeyEvent) de votre Activity. Ceux-ci doivent être délégués à la vue du lecteur:

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

Il est important de demander la sélection de la vue du lecteur pour naviguer dans les commandes de lecture et ignorer les annonces. Envisagez de demander le focus dans onCreate de 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 vous utilisez Compose sur Android TV, vous devez rendre AndroidView sélectionnable et déléguer l'événement en transmettant le paramètre de modificateur dans AndroidView en conséquence:

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

Remplacer les drawables

PlayerView utilise PlayerControlView pour afficher les commandes de lecture et la barre de progression. Les drawables utilisés par PlayerControlView peuvent être remplacés par des drawables portant les mêmes noms que ceux définis dans votre application. Consultez la documentation Javadoc sur PlayerControlView pour obtenir la liste des drawables de contrôle pouvant être remplacés.

Personnalisation avancée

Lorsqu'une personnalisation au-delà de celle décrite ci-dessus est requise, les développeurs d'applications devraient implémenter leurs propres composants d'interface utilisateur plutôt que d'utiliser ceux fournis par le module d'interface utilisateur de Media3.