Réaliser un lecteur vidéo HTML5 personnalisé

Dans ce tutoriel nous allons voir comment réaliser un lecteur vidéo HTML5 personnalisé : voir la démonstration

demonstration_lecteur_video_HTML5

La balise HTML5 <video> permet la lecture de vidéos directement sans installation de plugins/codecs. La plupart des navigateurs propose un lecteur prédéfini mais il peut être intéressant de le personnaliser en fonction du design du site dans lequel on va l’intégrer. En effet il peut y avoir des différences de couleurs/formes suivant le navigateur utilisé comme montré ci-dessous :

lecteurs_videos_HTML5
Rendus des lecteurs vidéos HTML5 par défaut sous Firefox, Chrome et Opera

Formats vidéo

Avant d’attaquer le tutoriel nous allons un peu parler des différents formats vidéos qui peuvent être utilisé pour la balise <video>. Ils sont au nombre de 3 : le Webm, le MP4, le OGV. Il est essentiel d’avoir au moins 2 de ces formats vidéo différents pour que la vidéo puisse être lue sur tous les navigateurs :

  • soit webm et MP4
  • soit OGV et MP4

En effet Webm et OGV peuvent être lu sur Firefox, Opera et Google Chrome alors que Safari et Internet Explorer 9 supporte uniquement le MP4. C’est un des inconvénient pour le moment du HTML5 pour lire des vidéo : la nécessité d’avoir 2 formats différents.

Voici les liens pour télécharger la vidéo de démo que nous allons utiliser (format webm et MP4) : Télécharger la vidéo WEBMTélécharger la vidéo MP4

Pour que votre serveur web reconnaisse ces formats il faut ajouter un fichier .htaccess à la racine de votre dossier avec ces 3 lignes :

AddType video/mp4 .mp4
AddType video/webm .webm
AddType video/ogg .ogv

Cela permettra à votre serveur web d’envoyer au navigateur les types MIME corrects pour les fichiers webm, mp4 et ogv. Ceci fait nous pouvons passer à proprement parlé au tutoriel.

Intégration HTML/CSS

Commençons par définir le code HTML de base pour l’intégration de la vidéo :

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div id="content">
    <video width="800" type="video/webm">
      <source src="video.webm" type="video/webm" />
      <source src="video.mp4" type="video/mp4" />
      Votre navigateur ne supporte pas la balise HTML5 vidéo
    </video>
    <div id="controls">
      <img src="img/fullscreen.png" id="fullscreen" alt="<>" />
      <img src="img/play.png" id="play" alt=">" />
      <img src="img/pause.png" id="pause" alt"||" />
      <img src="img/stop.png" id="stop" alt="S" />
      <div id="time"></div><img src="img/volume.png" id="btn_volume" alt="V" />
      <div id="volume"></div>
    </div>  
  </div>
</body>
</html>

Et le minimum de CSS pour que le tout s’affiche correctement :

#content {
  width: 800px;
  margin-left: auto;
  margin-right: auto;
  text-align: left;
}

#video {
  z-index: 1;
}

#controls {
  position: relative;
  z-index: 2;
  background: #ccc;
  padding: 3px;
}

#time {
  width: 505px;
  display: inline-block;
}

#btn_volume {
  margin-left: 5px;
}

#volume {
  float: right;
  width: 100px;
  margin-top: 12px;
}

#fullscreen {
  float: right;
  margin-left: 15px;
  margin-top: 5px;
}

Voici les différentes fonctionnalités que nous allons mettre en place pour notre lecteur :

  • un bouton lecture
  • un bouton pause
  • un bouton stop
  • une barre de progression
  • un réglage du volume
  • un bouton pour passer en plein écran

C’est à ça que va servir tout ce qui est dans le <div id= »controls »> :

<div id="controls">
  <img src="img/fullscreen.png" id="fullscreen" alt="<>" />
  <img src="img/play.png" id="play" alt=">" />
  <img src="img/pause.png" id="pause" alt"||" />
  <img src="img/stop.png" id="stop" alt="S" />
  <div id="time"></div><img src="img/volume.png" id="btn_volume" alt="V" />
<div id="volume"></div>

Les 4 images sont les 4 boutons lecture, pause, stop et plein écran, le <div> avec l’id time servira pour la barre de progression, l’image et le dernier <div> pour le réglage du volume. Télécharger les icônes utilisées dans la démo

Ajoute de librairies JavaScript

Nous allons ajouter les librairies JQuery et JQuery UI, qui nous utiliserons par la suite, notamment pour réaliser la barre de progression de la vidéo ainsi que le régleur de volume. Voici le code à ajouter dans le <head> :

<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

Donc les 2 librairies JQuery et JQuery UI plus la feuille de styles propre à JQuery UI.

Réalisation des fonctionnalités de lecture avec Javascript/JQuery

Maintenant que tout est prêt commençons par réaliser les 3 fonctions de bases : lecture, pause et stop. Ajoutez ce code dans le <head> après les 3 fichiers que nous avons inclut tout à l’heure :

<script>
$(document).ready(function(){
  //joue la vidéo
  $("#play").click(function(){
    $('video')[0].play();
  });

  //met en pause la vidéo
  $("#pause").click(function(){
    $('video')[0].pause();
  });

  //stop la vidéo
  $("#stop").click(function(){
    $('video')[0].pause();
    $('video')[0].currentTime = 0;
  });
});
</script>

Donc pour chaque bouton on effectue l’action correspondante lorsque l’événement click est déclenché :

  • pour lancer la lecture on appelle la méthode play sur la vidéo
  • pour mettre en pause on appelle la méthode pause sur la vidéo
  • pour stopper il n’existe pas de méthode stop. Il faut appeler la méthode pause et remettre la vidéo au début : currentTime = 0

Vous pouvez testez dans votre navigateur que vos 3 boutons fonctionnent correctement.

Passons maintenant à la barre de progression de la vidéo. Celle-ci doit avancer en même temps que la vidéo se lit et être cliquable pour l’internaute puisse atteindre directement le moment voulu.

Nous allons utiliser pour ce faire le plugin Progress Bar fournit par la librairie JQuery UI. Ce plugin permet comme son nom l’indique de créer une barre de progression. Voici le code pour l’initialiser (à placer dans le $(document).ready) :

$("#time").progressbar();

Voila notre barre de progression est créer. Il faut maintenant la synchroniser avec la vidéo. Mettons donc en place une petite fonction que nous nommerons setTime et qui se chargera de faire avancer la barre de progression (à placer avant $(document).ready) :

function setTime() {
  $("#time").progressbar({ value: $('video')[0].currentTime*100/$('video')[0].duration });
}

On récupère où en est la vidéo (currentTime) et on ramène en pourcentage par rapport à la durée totale de la vidéo : duration

Maintenant il ne nous reste plus qu’a appeler cette fonction régulièrement pour que la barre de progression reste synchronisée avec la vidéo. Il suffit de rajouter cette ligne dans $(« #play »).click :

 setInterval("setTime()", 10);

On appelle la fonction setTime() toutes les 10 millisecondes, ainsi la barre de progression reste tout le temps en phase avec la vidéo.

Maintenant il faudrait que lorsque l’internaute se déplace dans la barre de progression la vidéo fasse de même. C’est la partie la plus complexe à réaliser… En effet lorsque l’utilisateur va cliquer dans la barre de progression on ne va pas pouvoir directement récupérer une valeur entre 0 et 100 qui nous indiquerait à quel endroit lire la vidéo : on va récupérer la distance en pixels entre le bord de la fenêtre du navigateur et la position du curseur de la souris. Un petit schéma pour mieux comprendre :
x_progressbar
On va récupérer la distance rouge (distance bord de la fenêtre – curseur). La valeur qui nous intéresse c’est la verte (distance bord de la barre – curseur). Il faut donc faire rouge moins bleu (distance bord de la fenêtre – bord de la barre).

Nous allons utiliser cette fonction qui permet de déterminer la position d’un élément HTML dans la page (à placer avant $(document).ready) :

function findPos(el) {
  var x = y = 0;    
  if(el.offsetParent) {    
    x = el.offsetLeft;    
    y = el.offsetTop;    
    while(el = el.offsetParent) {    
      x += el.offsetLeft;    
      y += el.offsetTop;    
    }    
  }    
  return {'x':x, 'y':y};    
}

Ensuite placez ce code dans $(document).ready :

$('#time').click(function(e) {
  var ev = e || window.event;
  var pos = findPos(this);      
  var diffx = ev.clientX - pos.x;      
  $("#time").progressbar({value: diffx*100/$(this).width()});
  var duration = $('video')[0].duration;
  $('video')[0].currentTime = diffx*duration/$(this).width();      
});

On récupère donc la distance rouge du schéma plus haut (ev.clientX) à laquelle on va soustraire le distance bleu (pos.x). Ensuite il suffit de placer la barre de progression à l’endroit cliqué : diffx ramené en pourcentage par rapport à la longueur total de la barre de progression. Et de définir où on doit se placer dans la vidéo : diffx ramené par rapport à la durée total de la vidéo.

Voila pour la barre de progression, passons au réglage du volume.

Nous allons pour cette étape utiliser un autre plugin de JQuery UI : Slider. Celui ci va nous permettre de créer un sélecteur glissant permettant de choisir le niveau du voulme.

Voici le code pour l’initialiser (à placer dans $(document).ready) :

$("#volume").slider({
  slide: function(event, ui) {
  var volume = ui.value/100;
  setVolume(volume);
  },
  value: 50
});

On réalise ici 2 choses en même temps :

  • on initialise le sélecteur glissant avec une valeur par défaut à la moitié (50 sur 100)
  • on définit quoi faire lorsque l’internaute bougera le sélecteur : on appellera la fonction setVolume() qui va s’occuper de définir le niveau du volume qu’on lui passe en paramètre

Cette fonction n’existe pas il faut la créer :

function setVolume(value)
{
  if(value == 0)
    $("#btn_volume").css('opacity', 0.3);
  else
    $("#btn_volume").css('opacity', 1.0);
  $("#volume").slider("option", "value", value*100);
  $('video')[0].volume = value;
}

On grise/dégrise l’icône de volume si le niveau du volume est définit à 0 ou non, on définit la position du sélecteur de volume suivant le niveau de volume et enfin on définit le niveau de volume de la vidéo.

Voila notre sélecteur de volume fonctionne. On peut faire une dernière chose : permettre à l’internaute de couper le son quand il clique sur l’icône de volume :

$("#btn_volume").click(function(){
  var volume = $("#volume").slider("option", "value");
  if(volume > 0)
    setVolume(0);
  else
    setVolume(0.5);
});

On définit le volume à 0 si il n’est pas déjà coupé ou on le rétablit à la moitié si c’est le cas.

Notre lecteur vidéo HTML5 est presque terminé ! Passons à la dernière étape : le plein écran.

//plein écran
$("#fullscreen").click(function(){
      
        var video = $('#video').get(0);
        if(video.requestFullScreen) {
                //fonction officielle du w3c
                video.requestFullScreen();
        } else if(video.webkitRequestFullScreen) {
                //fonction pour Google Chrome (on lui passe un argument pour autoriser le plein écran lors d'une pression sur le clavier)
                video.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
        } else if(video.mozRequestFullScreen){
                //fonction pour Firefox
                video.mozRequestFullScreen();
        } else { //fallback pour anciens navigateurs
              //si pas déjà en pleine écran
              if($('#video').attr('rel') != 'fullscreen')
              {
                //on met la vidéo en pleine écran
                $('#video').css({position: 'absolute', top: 0, left: 0, width: '100%', height: '100%'}).attr('rel', 'fullscreen');
                //on met la barre de controles en bas de la page
                $('#controls').css({position: 'absolute', bottom: 0, marginLeft: 'auto', marginRight: 'auto'});
                //la barre apparait si on passe dessus
                setTimeout("$('#controls').animate({opacity : 0.0}, 500);", 1000);
                $('#controls').hover(function(){
                  $(this).animate({opacity : 1.0}, 200);
                }, function(){
                  $(this).animate({opacity : 0.0}, 500);
                });
              }
              else
              {
                //on remet la vidéo en mode normal
                $('#video').removeAttr('style').removeAttr('rel');
                //on remet la barre de control en dessous de la vidéo
                $('#controls').animate({opacity : 1.0}, 1).off('hover').removeAttr('style').removeAttr('style');
              }    
        }
        
      });
    $('#controls').animate({opacity : 1.0}, 1).off('hover').removeAttr('style');
  }    
});

On vérifié si la vidéo est déjà en pleine écran (attribut rel=’fullscreen’). Si elle ne l’est pas :

  • on l’agrandit à la taille de la fenêtre (position en 0,0 et taille 100%)
  • on position les contrôles du lecteur en bas de page (bottom = 0) et on la cache (opacity = 0.0)
  • au survol de la barre de contrôle et on la fait réapparaitre

Si la vidéo est déjà en plein écran on la ramène en mode « normal » :

  • on supprime les attributs ‘style’ et ‘rel’ de la vidéo
  • on refait apparaitre la barre de contrôle, on supprime l’événement de survol et on supprime l’attribut ‘style’

Voila notre lecteur personnalisé est maintenant terminé. Vous pouvez consulter la démonstration finale et télécharger l’archive ZIP de ce tutoriel. N’hésitez à laisser un commentaire ou des remarques si besoin.

19 Commentaires

  1. Merci pour cet article détaillé et de qualité!

  2. Salut je suis novice en javasprict jqwery, je voulais savoir comment tu fais pour étendre le fullscreen sur tout l’écran et pas seulement la fenêtre.

    • Je ne sais pas si il est possible en Javascript de passer en pleine écran. Dans mon tutoriel j’applique simplement un 100% sur la width et height de la balise video (en position absolute).
      Fais quelques recherche sur le net voir si il est possible de faire autrement…

  3. Bonjour,

    Merci pour ce très bon tutoriel que je cherchais depuis un certain temps. Heureux de l’avoir trouvé. Une simple question : comment changer le code pour faire en sorte que le slider son s’affiche verticalement ?
    J’ai fait quelques tentatives en intervertissant les coordonnées x et y du curseur et en changeant la balise width par la balise height mais rien n’y fait.

    Cordialement.

    • Bonjour,

      Je me suis un peu mélangé les pinceaux entre la barre de progression de la vidéo et le slider son. J’aimerai donc avoir un slider son vertical. En le faisant en CSS le bouton se retrouve tout en haut et non pas à mi hauteur. Est-ce possible avec ce plugin ou bien faut-il en utiliser un autre ?

      Cordialement.

  4. Bonsoir,

    J’ai un soucis avec le son. Le curseur de la barre du son ne bouge pas. J’ai vérifié le code plusieurs fois et tout semble OK. Que puis-je faire pour régler ce problème ?

    Cordialement.

    • Bonjour,

      Finalement tout fonctionne parfaitement. Concernant le curseur pour le son, j’ai compris qu’il suffisait de cliquer dans la barre de son pour que le curseur monte et descende avec le son. J’ai mal compris les instructions jquery car je pensais que l’événement attendu était de faire glisser le curseur le long de la barre de son !

      Bravo et merci encore 😉

  5. bonjour j’ai essayer votre méthode qui marche niquel mais lorsque je met un deuxième lecteur aucun contrôleur ne marche la barre de progression et volume n’apparait pas saurai tu d’ou viens le problème?

    • Bonjour,

      Le lecteur que je propose n’a pas été prévu pour être intégré plusieurs fois sur la même page.
      Pour cela il vous faut remplacer tous les id par des classes, et de même dans les sélecteurs jQuery ( $(« .controls ») au lieu de $(« #controls ») )

  6. Bonjour,

    Tout d’abord, merci pour votre tutoriel très détaillé.

    Dans la page pour laquelle j’ai mis l’adresse ci-dessus, je souhaite insérer une vidéo (ce n’est pas celle actuellement sur la page, celle-ci étant juste un essai). J’ai donc utilisé votre player (en supprimant le bouton stop). Cependant, tout fonctionne sauf la mise en plein écran.

    J’ai inséré la partie concernant le plein écran dans $(document).ready(function() après la partie sur le volume. Est-ce la bonne façon de faire ?
    Si c’est la bonne solution, je n’ai aucune idée d’où peut venir le problème…
    J’ai copié mon code dans un fichier txt accessible ici : http://dip01.u-grenoble3.fr/~tissota/ngprod/video.txt
    Pouvez-vous y jeter un oeil, peut-être ai-je fait une erreur ?

    Merci d’avance,

    Anaïs

    • Bonjour,

      J’ai regardé un peu ton code. Le problème vient de la ligne 81 :

      var video = $(‘#video’).get(0);

      Comme ta balise vidéo n’as pas l’ID « video » cela ne marche pas.
      Tu as 2 solutions : soit ajouter id= »video » sur ta balise video
      soit modifié le selecteur en mettant $(‘video’).get(0) (cela ne marchera que si tu n’as qu’une video sur ta page).

      Voila j’espère t’avoir aidé.

      PS : Je vois que ta page se trouve sur le site de l’Université Stendhal de Grenoble. Tu étudies dans quelle branche ?
      J’ai été étudiant en informatique pendant 2 ans à Grenoble mais à l’IUT2, près de la gare 🙂

  7. Salut, super explications….
    Par contre, est il possible de supprimer la barre de lecture ?

    Merci

  8. merci pour ton tutoriel il est vraiment génial jeannot depuis yaounde au cameroun

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.