1. Avant de commencer
Capture d'écran : application YouTube pour Android, avec ExoPlayer comme lecteur vidéo.
ExoPlayer est un lecteur multimédia au niveau de l'application, conçu à partir d'API multimédias de base dans Android. Il s'agit d'un projet Open Source utilisé par les applications Google, y compris YouTube et Google TV. ExoPlayer est extrêmement personnalisable et extensible. C'est pourquoi il convient à de nombreux cas d'utilisation avancés. Il est compatible avec divers formats multimédias, y compris des formats adaptatifs tels que DASH et SmoothStreaming.
Prérequis
- Une certaine connaissance du développement sur Android et d'Android Studio
Objectifs de l'atelier
- Créer une instance
ExoPlayer
, qui prépare et lit les contenus multimédias depuis différentes sources - Intégrer ExoPlayer au cycle de vie d'une activité de l'application, pour permettre le passage en arrière-plan et au premier plan, ainsi que la reprise de la lecture dans un environnement à une ou plusieurs fenêtres
- Utiliser des
MediaItem
pour créer une playlist - Lire des flux vidéo adaptatifs, qui adaptent la qualité du contenu multimédia à la bande passante disponible
- Enregistrer des écouteurs d'événements pour surveiller l'état de la lecture et afficher la façon dont les écouteurs peuvent être utilisés pour mesure la qualité de la lecture
- Utiliser des composants standards de l'UI d'ExoPlayer, puis les personnaliser pour les adapter au style de votre application
Ce dont vous avez besoin
- Vous disposez de la dernière version stable d'Android Studio et savez comment l'utiliser. Assurez-vous qu'Android Studio, le SDK Android et le plug-in Gradle sont à jour.
- Vous devez également disposer d'un appareil Android fonctionnant sous JellyBean (4.1) ou version ultérieure (idéalement Nougat (7.1) ou version ultérieure, car il est possible d'utiliser plusieurs fenêtres avec cette version de l'OS)
2. Configuration
Obtenir le code
Pour commencer, téléchargez le projet Android Studio :
Vous pouvez également cloner le dépôt GitHub :
git clone https://github.com/googlecodelabs/exoplayer-intro.git
Structure des répertoires
Une fois le dépôt cloné ou décompressé, vous pouvez accéder au dossier racine (exoplayer-intro
), qui contient un projet Gradle composé de plusieurs modules : un module d'application et un module pour chaque étape de cet atelier de programmation, avec toutes les ressources nécessaires.
Importer le projet
- Lancez Android Studio.
- Sélectionnez Fichier > Nouveau > Importer un projet*.*
- Sélectionnez le fichier racine
build.gradle
.
Capture d'écran : structure du projet importé
Une fois le projet compilé, six modules s'affichent : le module app
(de type application) et cinq modules nommés exoplayer-codelab-N
(où N
correspond à un chiffre compris entre 00
et 04,
, chacun de type bibliothèque). Le module app
ne contient qu'un fichier manifeste. L'intégralité du module exoplayer-codelab-N
spécifié fusionne lorsque l'application est compilée avec une dépendance Gradle dans app/build.gradle
.
app/build.gradle
dependencies {
implementation project(":exoplayer-codelab-00")
}
L'activité du lecteur multimédia est conservée dans le module exoplayer-codelab-N
. Si elle reste stockée dans un module de bibliothèque distinct, c'est pour que vous puissiez la partager entre des APK ciblant différentes plates-formes (mobile et Android TV, par exemple). De plus, vous pouvez ainsi profiter de certaines fonctionnalités, comme Dynamic Delivery, qui permet d'installer votre fonctionnalité de lecture de contenus multimédias uniquement lorsque l'utilisateur en a besoin.
- Déployez et exécutez l'application pour vérifier que tout fonctionne bien. L'application doit remplir l'écran avec un arrière-plan noir.
Capture d'écran : application vide en cours d'exécution
3. Diffuser des contenus en streaming
Ajouter une dépendance ExoPlayer
ExoPlayer fait partie de la bibliothèque Jetpack Media3. Chaque version est identifiée de manière unique par une chaîne au format suivant :
androidx.media3:media3-exoplayer:X.X.X
Vous pouvez ajouter ExoPlayer à votre projet en important simplement ses classes et composants d'UI. Ce projet est plutôt de petite taille, avec une empreinte minime d'environ 70 à 300 ko, selon les fonctionnalités incluses et les formats pris en charge. La bibliothèque d'ExoPlayer est divisée en modules pour que les développeurs puissent importer uniquement la fonctionnalité dont ils ont besoin. Pour en savoir plus sur la structure modulaire d'ExoPlayer, reportez-vous à la section Ajouter des modules ExoPlayer.
- Ouvrez le fichier
build.gradle
du moduleexoplayer-codelab-00
. - Ajoutez les lignes ci-dessous à la section
dependencies
, puis synchronisez le projet.
exoplayer-codelab-00/build.gradle
def mediaVersion = "1.0.0-alpha03"
dependencies {
[...]
implementation "androidx.media3:media3-exoplayer:$mediaVersion"
implementation "androidx.media3:media3-ui:$mediaVersion"
implementation "androidx.media3:media3-exoplayer-dash:$mediaVersion"
}
Ajouter l'PlayerView element
- Ouvrez le fichier de ressources de mise en page
activity_player.xml
depuis le moduleexoplayer-codelab-00
. - Placez le curseur dans l'élément
FrameLayout
. - Commencez à saisir
<PlayerView
et laissez Android Studio remplir automatiquement l'élémentPlayerView
. - Utilisez
match_parent
comme valeur pourwidth
etheight
. - Déclarez
video_view
comme ID.
activity_player.xml
<androidx.media3.ui.PlayerView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Dans la suite de cet atelier, cet élément d'interface utilisateur sera appelé "vue de la vidéo".
- Dans
PlayerActivity
, vous pouvez à présent obtenir une référence pour l'arborescence de vues, créée à partir du fichier XML que vous venez de modifier.
PlayerActivity.kt
private val viewBinding by lazy(LazyThreadSafetyMode.NONE) {
ActivityPlayerBinding.inflate(layoutInflater)
}
- Définissez la racine de votre arborescence de vues comme vue de contenu de votre activité. Vérifiez également que la propriété
videoView
est visible dans votre référenceviewBinding
et que son type estPlayerView
.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(viewBinding.root)
}
Créer une instance d'ExoPlayer
Pour lire un contenu multimédia en streaming, vous avez besoin d'un objet ExoPlayer
. Le plus simple pour en créer un consiste à utiliser la classe ExoPlayer.Builder
. Comme son nom l'indique, elle se sert du schéma de compilateur pour compiler une instance ExoPlayer
.
L'instance ExoPlayer
est une implémentation polyvalente pratique de l'interface Player
.
Ajoutez une méthode privée initializePlayer
pour créer votre instance ExoPlayer
.
PlayerActivity.kt
private var player: ExoPlayer? = null
[...]
private fun initializePlayer() {
player = ExoPlayer.Builder(this)
.build()
.also { exoPlayer ->
viewBinding.videoView.player = exoPlayer
}
}
Créez une classe ExoPlayer.Builder
en utilisant votre contexte, puis appelez build
pour créer votre objet ExoPlayer
. Celui-ci est ensuite attribué à player
, que vous devez déclarer comme champ de membre. Ensuite, utilisez la propriété modifiable viewBinding.videoView.player
pour lier player
à la vue correspondante.
Créer un élément multimédia
Vous avez à présent besoin de contenus à lire pour votre objet player
. Pour cela, créez un MediaItem
. Il existe de nombreux types d'éléments MediaItem
. Pour commencer, vous allez en créer un pour un fichier MP3 sur Internet.
La façon la plus simple de créer un MediaItem
consiste à utiliser MediaItem.fromUri
, qui accepte l'URI d'un fichier multimédia. Ajoutez le MediaItem
au player
à l'aide de player.setMediaItem
.
- Ajoutez le code suivant à
initializePlayer
dans le blocalso
:
PlayerActivity.kt
private fun initializePlayer() {
[...]
.also { exoPlayer ->
[...]
val mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3))
exoPlayer.setMediaItem(mediaItem)
}
}
Notez que la valeur de R.string.media_url_mp3
est https://storage.googleapis.com/exoplayer-test-media-0/play.mp3 dans strings.xml
.
Optimiser le cycle de vie de l'activité
L'instance player
peut consommer énormément de ressources, y compris pour la mémoire, le processeur, les connexions réseau et les codecs matériels. Un grand nombre de ces ressources est limité, surtout pour les codecs matériels qui ne peuvent avoir qu'une seule ressource. Il est important que vous libériez ces ressources pour les autres applications à utiliser lorsque vous ne vous en servez pas, par exemple quand votre application est mise en arrière-plan.
Autrement dit, le cycle de vie de votre lecteur doit être lié au cycle de vie de votre application. Pour cela, vous devez ignorer les quatre méthodes de PlayerActivity
: onStart
, onResume
, onPause
et onStop
.
- Ouvrez
PlayerActivity
, puis cliquez sur Code menu (Menu du code) > Override methods (Ignorer les méthodes). - Sélectionnez
onStart
,onResume
,onPause
etonStop
. - Initialisez le lecteur dans le rappel
onStart
ouonResume
, selon le niveau d'API.
PlayerActivity.kt
public override fun onStart() {
super.onStart()
if (Util.SDK_INT > 23) {
initializePlayer()
}
}
public override fun onResume() {
super.onResume()
hideSystemUi()
if ((Util.SDK_INT <= 23 || player == null)) {
initializePlayer()
}
}
Le niveau d'API Android 24 (et supérieur) gère plusieurs fenêtres. Comme votre application peut être visible et inactive en mode fenêtre partagée, vous devez initialiser le lecteur dans onStart
. Pour les niveaux d'API Android 23 et inférieurs, vous devez patienter jusqu'à ce que vous récupériez les ressources. Vous devez donc attendre onResume
pour pouvoir initialiser le lecteur.
- Ajoutez la méthode
hideSystemUi
.
PlayerActivity.kt
@SuppressLint("InlinedApi")
private fun hideSystemUi() {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowInsetsControllerCompat(window, viewBinding.videoView).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}
}
hideSystemUi
est une méthode d'assistance appelée dans onResume
. Cette méthode vous permet d'afficher le lecteur en plein écran.
- Libérez les ressources avec
releasePlayer
(que vous allez créer juste après) dansonPause
etonStop
.
PlayerActivity.kt
public override fun onPause() {
super.onPause()
if (Util.SDK_INT <= 23) {
releasePlayer()
}
}
public override fun onStop() {
super.onStop()
if (Util.SDK_INT > 23) {
releasePlayer()
}
}
Pour les niveaux d'API 23 et inférieurs, vous n'avez aucune certitude qu'onStop
sera appelé. Vous devez donc libérer le lecteur dès que possible dans onPause
. Pour les niveaux d'API 24 et supérieurs (qui proposent les modes Multifenêtre et Fenêtre partagée), onStop
sera obligatoirement appelé. Lorsqu'elle est en pause, votre activité reste visible. Vous devez donc attendre onStop
pour libérer le lecteur.
Vous devez à présent créer une méthode releasePlayer
, qui libère les ressources du lecteur et le détruit.
- Ajoutez le code suivant à l'activité :
PlayerActivity.kt
private var playWhenReady = true
private var currentItem = 0
private var playbackPosition = 0L
[...]
private fun releasePlayer() {
player?.let { exoPlayer ->
playbackPosition = exoPlayer.currentPosition
currentItem = exoPlayer.currentMediaItemIndex
playWhenReady = exoPlayer.playWhenReady
exoPlayer.release()
}
player = null
}
Avant de libérer et de détruire le lecteur, stockez les informations suivantes :
- État de lecture/pause avec
playWhenReady
- Position actuelle de la lecture avec
currentPosition
- Index d'élément multimédia actuel utilisant
currentMediaItemIndex
.
Il vous suffit de fournir ces informations d'état lorsque vous initialisez le lecteur pour que l'utilisateur puisse reprendre la lecture là où il l'avait arrêtée.
Derniers préparatifs
À présent, il ne vous reste plus qu'à fournir à votre lecteur, pendant l'initialisation, les informations d'état que vous avez enregistrées dans releasePlayer
.
- Ajoutez le code suivant à
initializePlayer
:
PlayerActivity.kt
private fun initializePlayer() {
[...]
exoPlayer.playWhenReady = playWhenReady
exoPlayer.seekTo(currentItem, playbackPosition)
exoPlayer.prepare()
}
Voilà ce qui se passe :
playWhenReady
indique au lecteur s'il doit démarrer la lecture dès que toutes les ressources pour la lecture ont été acquises. CommeplayWhenReady
est défini surtrue
au départ, la lecture démarre automatiquement la première fois que l'application est lancée.seekTo
indique au lecteur de rechercher une certaine position dans un élément multimédia spécifique.currentItem
etplaybackPosition
sont tous deux mis à zéro afin que la lecture démarre dès le début la première fois que l'application est lancée.prepare
signale au lecteur qu'il doit acquérir toutes les ressources requises pour la lecture.
Lire le fichier audio
Vous avez enfin terminé ! Lancez l'application pour lire le fichier MP3 et voir l'image intégrée.
Capture d'écran : l'application lit un seul titre.
Tester le cycle de vie de l'activité
Testez si l'application fonctionne dans tous les états du cycle de vie de l'activité.
- Lancez une autre application et remettez votre application au premier plan. Est-ce qu'elle reprend à la bonne position ?
- Mettez l'application en pause et passez-la en arrière-plan, puis à nouveau au premier plan. Est-ce qu'elle est toujours en pause lorsqu'elle passe en arrière-plan ?
- Faites pivoter l'application. Son comportement change-t-il si vous passez du mode Portrait au mode Paysage et inversement ?
Lire une vidéo
Pour lire une vidéo, il vous suffit de remplacer l'URI de l'élément multimédia par un fichier MP4.
- Remplacez l'URI dans
initializePlayer
parR.string.media_url_mp4
. - Relancez l'application et testez son comportement, y compris lorsqu'elle est mise en arrière-plan alors qu'une vidéo est en cours de lecture.
PlayerActivity.kt
private fun initializePlayer() {
[...]
val mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp4))
[...]
}
PlayerView
se charge de tout. Ici, c'est la vidéo qui est affichée en plein écran, pas l'image.
Capture d'écran : l'application lit une vidéo.
Félicitations ! Vous venez de créer une application pour diffuser un fichier multimédia sur Android en streaming et en plein écran, avec la gestion du cycle de vie, les enregistrements des états et les commandes d'interface utilisateur.
4. Créer une playlist
Votre application actuelle lit un seul fichier multimédia, mais que faire si vous voulez en lire plusieurs d'affilée ? Pour cela, vous avez besoin d'une playlist.
Vous pouvez créer une playlist en ajoutant plusieurs éléments MediaItem
au player
à l'aide d'addMediaItem
. Cela permet d'enchaîner la lecture des fichiers de manière fluide. La mise en mémoire tampon étant gérée en arrière-plan, aucune icône de chargement ne s'affiche lorsque l'utilisateur passe d'un élément multimédia à un autre.
- Ajoutez le code suivant à
initializePlayer
:
PlayerActivity.kt
private void initializePlayer() {
[...]
exoPlayer.addMediaItem(mediaItem) // Existing code
val secondMediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3))
exoPlayer.addMediaItem(secondMediaItem)
[...]
}
Vérifiez le comportement des commandes du lecteur. Vous pouvez utiliser les boutons et
pour parcourir la liste des éléments multimédias.
Capture d'écran : commandes de lecture, avec les boutons Précédent et Suivant
C'est plutôt pratique ! Pour en savoir plus, reportez-vous à la documentation pour les développeurs sur les éléments multimédias et les playlists, ainsi qu'à cet article sur l'API Playlist.
5. Streaming adaptatif
Le streaming adaptatif est une technique de streaming de fichiers multimédias qui consiste à adapter la qualité du flux à la bande passante réseau disponible. L'utilisateur bénéficie ainsi de la meilleure qualité possible pour sa bande passante.
Généralement, le même contenu multimédia est divisé en plusieurs titres de différentes qualités (débits et résolutions). Le lecteur choisit le titre en fonction de la bande passante réseau disponible.
Chaque titre est sectionné en fragments d'une certaine durée, généralement entre 2 et 10 secondes. Cela permet au lecteur de passer rapidement d'un titre à l'autre en fonction de l'évolution de la disponibilité de la bande passante. Le lecteur se charge ensuite d'assembler à nouveau ces fragments pour que la lecture soit fluide.
Sélection de titres adaptative
Sélectionner le titre le plus adapté à l'environnement actuel est une opération centrale du streaming adaptatif. Mettez à jour votre application pour lire des fichiers multimédias en streaming en utilisant la sélection de titres adaptative.
- Mettez à jour
initializePlayer
avec le code suivant :
PlayerActivity.kt
private fun initializePlayer() {
val trackSelector = DefaultTrackSelector(this).apply {
setParameters(buildUponParameters().setMaxVideoSizeSd())
}
player = ExoPlayer.Builder(this)
.setTrackSelector(trackSelector)
.build()
[...]
}
Tout d'abord, créez un DefaultTrackSelector
, qui sera chargé de sélectionner les titres dans l'élément multimédia. Ensuite, indiquez à votre trackSelector
de ne sélectionner que les titres de définition standard ou inférieure. Il s'agit d'un moyen efficace d'économiser les données de l'utilisateur (au détriment de la qualité). Enfin, transférez votre trackSelector
à votre compilateur pour qu'il soit utilisé lors de la compilation de l'instance ExoPlayer
.
Créer un MediaItem adaptatif
DASH est un format de streaming adaptatif couramment utilisé. Pour diffuser en streaming un contenu DASH, vous devez créer un MediaItem
, comme précédemment. Cependant, ici, vous devez utiliser MediaItem.Builder
au lieu de fromUri
,
car fromUri
utilise l'extension de fichier pour déterminer le format multimédia sous-jacent. Or, l'URI DASH ne possède pas d'extension de fichier. De ce fait, nous devons fournir un type MIME d'APPLICATION_MPD
pour créer le MediaItem
.
- Mettez à jour
initializePlayer
comme indiqué ci-dessous :
PlayerActivity.kt
private void initializePlayer() {
[...]
// Replace this line...
val mediaItem = MediaItem.fromUri(getString(R.string.media_url_mp4));
// ... with this
val mediaItem = MediaItem.Builder()
.setUri(getString(R.string.media_url_dash))
.setMimeType(MimeTypes.APPLICATION_MPD)
.build()
// Keep this line
exoPlayer.setMediaItem(mediaItem)
// Remove the following lines
val secondMediaItem = MediaItem.fromUri(getString(R.string.media_url_mp3))
exoPlayer.addMediaItem(secondMediaItem)
}
- Redémarrez l'application et observez le fonctionnement du streaming vidéo adaptatif avec DASH. C'est plutôt simple avec ExoPlayer.
Autres formats de streaming adaptatif
HLS (MimeTypes.APPLICATION_M3U8
) et SmoothStreaming (MimeTypes.APPLICATION_SS
) sont d'autres formats de streaming adaptatif courants qui sont compatibles avec ExoPlayer. Pour savoir comment créer d'autres sources multimédias adaptatives, reportez-vous à l'application de démonstration ExoPlayer.
6. Écouter les événements
Lors des étapes précédentes, vous avez vu comment lire en streaming des flux multimédias progressifs et adaptatifs. ExoPlayer effectue de nombreuses opérations en arrière-plan. Par exemple :
- Allouer la mémoire
- Télécharger les fichiers du conteneur
- Extraire les métadonnées du conteneur
- Décoder les données
- Afficher la vidéo et le texte à l'écran, et diffuser l'audio sur les enceintes
Il est parfois utile de savoir ce qu'ExoPlayer fait lors de l'exécution afin de comprendre et d'améliorer l'expérience de lecture pour vos utilisateurs.
Par exemple, vous pouvez décider de refléter les changements de l'état de lecture dans l'interface utilisateur en procédant comme suit :
- En affichant une icône de chargement lorsque le lecteur met les données en mémoire tampon
- En affichant le texte "À regarder ensuite" en superposition à la fin de la lecture du titre
ExoPlayer propose plusieurs interfaces d'écouteur qui fournissent des rappels pour les événements utiles. Un écouteur vous permet de consigner l'état dans lequel se trouve le lecteur.
Rester à l'écoute
- Créez une constante
TAG
en dehors de la classePlayerActivity
, que vous utiliserez par la suite pour la journalisation.
PlayerActivity.kt
private const val TAG = "PlayerActivity"
- Implémentez l'interface
Player.Listener
dans une fonction de fabrique en dehors de la classePlayerActivity
. Elle servira à vous signaler les événements importants du lecteur, y compris les erreurs et ses changements d'état. - Ignorez
onPlaybackStateChanged
en ajoutant le code suivant :
PlayerActivity.kt
private fun playbackStateListener() = object : Player.Listener {
override fun onPlaybackStateChanged(playbackState: Int) {
val stateString: String = when (playbackState) {
ExoPlayer.STATE_IDLE -> "ExoPlayer.STATE_IDLE -"
ExoPlayer.STATE_BUFFERING -> "ExoPlayer.STATE_BUFFERING -"
ExoPlayer.STATE_READY -> "ExoPlayer.STATE_READY -"
ExoPlayer.STATE_ENDED -> "ExoPlayer.STATE_ENDED -"
else -> "UNKNOWN_STATE -"
}
Log.d(TAG, "changed state to $stateString")
}
}
- Déclarez un membre privé de type
Player.Listener
dansPlayerActivity
.
PlayerActivity.kt
class PlayerActivity : AppCompatActivity() {
[...]
private val playbackStateListener: Player.Listener = playbackStateListener()
}
onPlaybackStateChanged
est appelé lorsque l'état de lecture change. Le nouvel état est donné par le paramètre playbackState
.
Les états du lecteur sont au nombre de quatre :
État | Description |
| Le lecteur a été instancié, mais n'a pas encore été préparé. |
| Le lecteur ne peut pas lire de fichiers depuis la position actuelle, car la quantité de données en mémoire tampon n'est pas suffisante. |
| Le lecteur peut démarrer immédiatement la lecture depuis la position actuelle. Cela signifie qu'il commencera à lire le fichier multimédia automatiquement si la valeur de la propriété playWhenReady est définie sur |
| Le lecteur a terminé de lire le fichier multimédia. |
Enregistrer votre écouteur
Pour que vos rappels soient appelés, vous devez enregistrer playbackStateListener
auprès du lecteur, dans initializePlayer
.
- Enregistrez l'écouteur avant que la lecture ne soit préparée.
PlayerActivity.kt
private void initializePlayer() {
[...]
exoPlayer.seekTo(currentWindow, playbackPosition)
exoPlayer.addListener(playbackStateListener)
[...]
}
Là aussi, vous devez nettoyer le code pour éviter que des références du lecteur restent présentes et provoquent une fuite de mémoire.
- Supprimez l'écouteur de
releasePlayer
:
PlayerActivity.kt
private void releasePlayer() {
player?.let { exoPlayer ->
[...]
exoPlayer.removeListener(playbackStateListener)
exoPlayer.release()
}
player = null
}
- Ouvrez logcat et exécutez l'application.
- Utilisez les commandes d'interface utilisateur pour rechercher, mettre en pause et reprendre la lecture. Vous devriez voir l'état de la lecture changer dans les journaux.
Aller plus loin
ExoPlayer propose d'autres écouteurs pratiques pour comprendre l'expérience de lecture de l'utilisateur. Il existe des écouteurs pour l'audio et la vidéo, ainsi qu'un AnalyticsListener
, qui contient les rappels de tous les écouteurs. Voici quelques-unes des méthodes les plus importantes :
- La méthode
onRenderedFirstFrame
est appelée lorsque le premier frame d'une vidéo est rendu. Vous pouvez alors calculer combien de temps l'utilisateur a dû attendre pour qu'un contenu satisfaisant s'affiche à l'écran. - La méthode
onDroppedVideoFrames
est appelée lorsque des frames vidéo ont été perdus. Une perte de frames indique que la lecture est mauvaise et que l'expérience utilisateur est probablement médiocre. - La méthode
onAudioUnderrun
est appelée si la mémoire tampon audio est sous-utilisée. Une telle sous-utilisation peut être à l'origine de problèmes audio plus perceptibles que la perte de frames.
AnalyticsListener
peut être ajouté à player
avec addListener
. Il existe également des méthodes équivalentes pour les écouteurs audio et vidéo.
L'interface Player.Listener
inclut également le rappel onEvents
, plus général, déclenché pour chaque changement d'état dans le lecteur. Cela peut être utile dans certains cas, par exemple pour répondre à plusieurs changements d'état simultanés ou pour répondre de la même manière à plusieurs changements d'état différents. Consultez la documentation de référence pour d'autres exemples d'utilisation du rappel onEvents
au lieu de rappels de changement d'état individuels.
Déterminez les événements importants pour votre application et vos utilisateurs. Pour en savoir plus, consultez Écouter des événements du lecteur. C'est tout pour les lecteurs d'événements !
7. Félicitations
Félicitations ! Vous avez appris beaucoup de choses concernant l'intégration d'ExoPlayer dans votre application.
En savoir plus
Pour en savoir plus sur ExoPlayer, consultez le guide du développeur et le code source, et abonnez-vous au blog ExoPlayer.