Contrôler la tête de lecture avec MediaElement
Alors aujourd’hui, nous allons commencer par implémenter le contrôle de la tête de lecture, pour permettre à l’utilisateur de se déplacer à un endroit précis du morceau.
Binding des composants
Si tu te rappelles bien, dans le chapitre sur l’affichage du temps d’écoute, nous avions introduit 3 composants :
ElapsedTime
qui est un Label pour afficher le temps écoulé de lecture,TotalTime
qui est aussi un Label, mais pour afficher la durée totale de la piste audio,et enfin le Slider
TimeTracker
, pour contrôler la tête de lecture de la piste.
Adieu les données factices ! Nous allons désormais donner vie à ces composants avec l’aide du Data Binding. Et on isolera tout ça dans une méthode d’initialisation InitTimeTracker() :
Nom du fichier :MusicPlayerView.cs
|
|
Oui je sais c’est un peu dense, courage ! Tout est détaillé juste après.
Pour commencer, nous avons modifié le comportement du TimeTracker
pour lui associer deux propriétés :
la position actuelle du curseur sur le Slider,
et la valeur maximale du curseur (quand il est positionné tout à droite).
Intéressons-nous maintenant d’un peu plus près au MediaElement incarné par notre composant MusicPlayer
. Celui-ci expose justement ce qu’il nous faut :
la position de la tête de lecture en temps réel (
MusicPlayer.Position
), à associer à la position du curseur sur le Slider (TimeTracker.Value
),et la durée totale du morceau (
MusicPlayer.Duration
), à associer à la valeur maximale du Slider (TimeTracker.Maximum
).
Enfin, si tu te rappelles bien, le Slider ne peut considérer que des valeurs de type double. C’est pourquoi nous avons besoin de convertir les valeurs obtenues avec MusicPlayer.Position
et MusicPlayer.Duration
, depuis le type TimeSpan vers le type double, avec la propriété TotalSeconds
.
Pour le composant ElapsedTime
, on veut qu’il affiche depuis combien de temps le morceau est joué en se basant lui aussi sur la propriété MusicPlayer.Position
. Seulement, on ne veut pas afficher n’importe quoi ! On veut en effet afficher une durée en minutes et en secondes. Pour cela, on a besoin de lui appliquer le format de texte souhaité avec l’aide du code : {0:mm\\:ss}
.
Pour le composant TotalTime
, on veut afficher le temps total d’écoute du morceau en se basant sur la propriété MusicPlayer.Duration
. Et de la même façon, on applique le même format de texte pour afficher une durée en minutes et en secondes.
Au fait, n’oublie pas de remplacer le signe “=>” par “=” à la déclaration de chacun de ces composants ! Sinon ça ne marchera pas puisque le même objet sera retourné à chaque appel à ces variables. On peut d’ailleurs en profiter aussi pour retirer les valeurs factices qu’on avait définies par défaut pour certaines propriétés :
Text
pour les Labels,Maximum
etValue
pour le Slider.
Et voici donc la déclaration actualisée pour ces 3 composants :
Nom du fichier :MusicPlayerView.cs
|
|
Enfin, la méthode d’initialisation de ces composants devra être appelée depuis le constructeur de la page :
Nom du fichier :MusicPlayerView.cs
|
|
Allez vas-y, relances le projet ! Je suis sûr que tu en meurs d’envie 😄
Normalement, tu devrais voir les textes s’initialiser correctement en se basant sur de vraies valeurs. Également, le curseur devrait se déplacer tout seul selon la progression de la lecture du morceau.
On peut s’amuser à colorer l’arrière-plan de nos Labels pour mieux se rendre compte de ce qu’il se passe :
Quand la lecture de la chanson progresse, le texte est actualisé à chaque seconde et une nouvelle valeur remplace l’ancienne. Seulement, on dirait que certaines valeurs nécessitent plus d’espace que d’autres ! 😄
Si tu te rappelles le chapitre sur les fondations, on y avait défini un composant Grid nommé BottomLayout
, que l’on a divisé en 7 colonnes de tailles différentes :
Nom du fichier :MusicPlayerView.cs
|
|
On va retravailler la structure de notre Grid en fusionnant les deux premières colonnes, et les deux dernières…
Nom du fichier :MusicPlayerView.cs
|
|
… puis retravailler la disposition des éléments du BottomLayout
:
Nom du fichier :MusicPlayerView.cs
|
|
Comme on a supprimé deux colonnes de notre Grid initiale, on a dû corriger le positionnement de nos composants sur la grille, en modifiant leur colonne assignée ainsi que leur alignement horizontal. Pour cela, nous avons eu recours aux méthodes Start() et End(). Elles permettent respectivement d’aligner un composant horizontalement au début ou à la fin de l’espace qui lui est disponible.
Et voilà le travail :
Contrôler la tête de lecture
Pour contrôler la tête de lecture, l’utilisateur doit simplement glisser le curseur du Slider d’un point A à un point B. En décomposant un peu plus son geste, on pourrait dire que :
L’utilisateur doit d’abord poser le doigt sur le curseur à un point A du Slider,
Puis il déplacera ce curseur en maintenant son doigt appuyé dessus,
Et enfin, il le relâchera à un point B du Slider en levant son doigt de l’écran.
En lisant cette description, est-ce que ça t’a mis la puce à l’oreille ?
Détecter le moment où l’utilisateur commence à déplacer le curseur,
Et détecter quand il le relâche.
Rattachons ces deux évènements à notre TimeTracker
depuis la méthode InitTimeTracker() :
Nom du fichier :MusicPlayerView.cs
|
|
Maintenant, définis ces nouveaux évènements dans la région des Events avec le code suivant :
Nom du fichier :MusicPlayerView.cs
|
|
Le premier évènement TimeTracker_DragStarted() correspond au moment où l’utilisateur commence à déplacer le curseur sur le Slider. Quand cela se produit, la lecture du morceau est mise en pause pour ne pas que la musique continue de jouer. Et d’ailleurs, le curseur continuerait de se déplacer tout seul !
Bien sûr, pour que l’expérience utilisateur soit bonne, il faut que la lecture du morceau reprenne aussitôt que l’utilisateur a terminé son mouvement. Pour cela, nous devons garder en mémoire le fait de devoir reprendre la lecture avec l’aide de la variable mustResumePlayback
.
Nom du fichier :MusicPlayerView.cs
|
|
Pour le second évènement TimeTracker_DragCompleted(), c’est le moment où l’utilisateur a fini de déplacer le curseur sur le Slider. Quand cela arrive, on repère la position du curseur pour alors réajuster la tête de lecture du MusicPlayer
conformément. Pour cela, on a recours à la méthode SeekTo() exposée par la classe du MediaElement, avec un temps de référence pour paramètre (au format TimeSpan).
MusicPlayer.Position
.Relance le projet et vérifie que tu peux avancer ou reculer dans le morceau !
Tu viens de terminer l’implémentation d’une belle fonctionnalité pour l’utilisateur, bravo !
La prochaine fois, nous verrons comment implémenter la gestion du volume. À très vite !
Plus d’articles dans la même série: