Bien que l'idée d'un élément HTML spécifique à la vidéo ait été suggérée il y a plus de dix ans, nous commençons tout juste à le voir se concrétiser! Oubliez tout ce charabia "HTML5 2012"; la vérité est que vous pouvez utiliser le vidéo
élément dans vos projets dès maintenant! Il vous suffit de connaître quelques exigences avant de vous lancer sans réfléchir..
document.createElement ('video')
. Curieusement, cela semble déclencher la prise de conscience d'IE. Oui, c'est assez étrange, mais c'est ce que nous attendons d'Internet Explorer, n'est-ce pas? Pour accélérer ce processus, Remy Sharp a créé HTML5 Shiv, qui corrige aussi certains problèmes d'impression lors de l'utilisation d'éléments HTML5. Il suffit de télécharger le script et de le référencer dans le tête
section de votre / vos document (s).ogg
format, alors que les navigateurs Webkit peuvent rendre mp4
vidéos. En fait, il s’agit d’une simplification excessive; cependant, cela fera pour le moment. Cependant, il suffit de dire que davantage de types de vidéos sont pris en charge, y compris le codec V8 récemment ouvert de Google.. Comme pour tout projet, notre première étape consiste à créer le supplément nécessaire à notre projet..
Lecteur vidéo HTML5 personnalisé Vidéo HTML5
Tout d’abord, trouvez des exemples de vidéos avec lesquels travailler. Je vais utiliser la vidéo open-source "Big Bunny Buck" de type Pixar. Je suis sûr que vous l'avez déjà utilisé sur le Web. L'affichage de cette balise dans le navigateur peut vous laisser un point d'interrogation au-dessus de votre tête.
Hein? C'est tout? Cela ressemble à une image. Quel est le problème? Eh bien, par défaut, c’est tout ce que nous avons demandé. Nous devons ensuite spécifier si les contrôles doivent être affichés, un poster, etc. Faisons-le maintenant. réviser votre vidéo
élément, comme si:
Dès le départ, nous remarquons qu'il n'y a pas de citations concernant les attributs. En fin de compte, ils ne sont pas nécessaires. Il y a des années, il était considéré comme une mauvaise pratique de les exclure, mais ce n'est plus le cas. À ce stade, il ne s'agit que de préférences personnelles. Donc, si vous vous sentez plus à l'aise de les ajouter, faites-le.
Nous ne savons évidemment pas quoi utiliser les contrôles par défaut du navigateur. En tant que tels, nous devons mettre en place notre propre système de contrôle. Avant de progresser, vous vous êtes peut-être demandé: "Alors, à quoi sert-il d’ajouter le les contrôles
attribuer du tout? La réponse est parce que nous devons prendre en compte et compenser le fait que JavaScript peut être désactivé sur l'ordinateur du spectateur. Dans ces cas, n’avions-nous pas ajouté le les contrôles
attribut, ils ne verraient que ce qui semble être une image.
Toujours considérer la possibilité que JavaScript soit désactivé.
le div
avec un identifiant de "videoControls" est l'endroit où nous allons ajouter les boutons et le logo nécessaires. Un petit truc astucieux est l'utilisation de "& # x25BA;" pour créer le bouton de lecture. Ne vous inquiétez pas trop de la "progression" div; Nous examinerons cette section plus en détail plus tard dans ce didacticiel. La réponse courte est qu'il s'agit du conteneur de notre barre de progression. Enfin, nous ajoutons un bouton
qui basculera la fonctionnalité plein écran, ainsi que le logo Tuts +.
Ne t'inquiète pas Bien qu'il semble que nous ayons maintenant créé un deuxième ensemble de contrôles (et que nous n'en ayons pas le style), nous supprimerons éventuellement les contrôles par défaut avec JavaScript. Néanmoins, la capture d'écran ci-dessus doit correspondre à votre propre aperçu, si vous suivez.
Avec le balisage terminé, nous pouvons maintenant passer à la partie amusante! Créez un nouveau dossier appelé "js" et ajoutez un nouveau fichier: videoPlayer.js
. Ensuite, soyons bons garçons et filles et intégrons notre code dans une fonction anonyme invocatrice, pour empêcher la création de variables globales inutiles.
(fonction (fenêtre, document) (this, document))
Vous pouvez éliminer les arguments si vous le souhaitez, c'est une petite amélioration avec deux avantages:
ce
(l'objet Window global) et document
, nous évitons au moteur JavaScript d'avoir à filtrer et à suivre ces objets. Cela peut être très pratique pour les grands projets, mais offre un très petit avantage en termes de performances.. la fenêtre
et document
peut maintenant être représenté via quelque chose comme une
et b
. Ensuite, continuons à garder notre code aussi propre que possible en créant un lecteur vidéo
objet qui contiendra toutes nos méthodes. Nous allons aussi créer un init
méthode qui sera appelée immédiatement lors du chargement de la page.
(fonction (fenêtre, document) var videoPlayer = init: function () ; videoPlayer.init (); (this, document))
Comme nous allons certainement manipuler des éléments sur la page, allons de l'avant et référençons leur emplacement dans des variables. Juste avant de déclarer la variable "videoPlayer", ajoutez:
var video = document.getElementsByTagName ('video') [0], videoControls = document.getElementById ('videoControls'), play = document.getElementById ('play'), progressContainer = document.getElementById ("progress"), progressHolder = document.getElementById ("progress_box"), playProgressBar = document.getElementById ("play_progress"), fullScreenToggleButton = document.getElementById ("fullScreen");
Si vous travaillez bien (et j'espère que vous le faites), prenez le temps d'apprendre exactement à quoi ces variables font référence. Reportez-vous à votre marge, si nécessaire. Nous prenons l’élément vidéo, les commandes vidéo, le bouton de lecture, le bouton bascule plein écran et les trois images de progression. Nous "cachons" l'emplacement de ces éléments car il n'y a aucune raison de parcourir inutilement le DOM chaque fois que nous devons accéder à l'un de ces éléments!
Init
Méthode Commençons à écrire du code réel. Dans le init
méthode, collez dans l'extrait suivant:
init: function () // c'est égal à l'objet videoPlayer. var que = ceci; // déclencheur CSS utile pour JS. document.documentElement.className = 'js'; // Supprimez les contrôles par défaut, car nous utiliserons les nôtres. video.removeAttribute ('contrôles'); // Lorsque les métadonnées sont prêtes, affichez les contrôles video.addEventListener ('loadeddata', this.initializeControls, false);
Une manière élégante de styliser les éléments en fonction de l'activation de JavaScript consiste à appliquer une classe de "js" au documentElement
, ou la html
élément.
// déclencheur CSS utile pour JS. document.documentElement.className = 'js';
Cela nous permet ensuite d’écrire CSS comme:
.js #container / * ce style n'est rendu que si JS est activé * /
Rappelez-vous le problème avec les deux ensembles de contrôles vidéo? Remédions à cela maintenant. C’est facile; nous allons simplement utiliser le removeAttribute
méthode, et se débarrasser de les contrôles
.
// Supprimez les contrôles par défaut, car nous utiliserons les nôtres. video.removeAttribute ('contrôles');
Ajoutons maintenant notre premier événement HTML5: loadeddata
. Cet événement se déclenche lorsque le navigateur a fini de charger les métadonnées de la vidéo. C’est un excellent endroit pour effectuer toutes les procédures initiales, telles que l’affichage de contrôles personnalisés..
// Lorsque les métadonnées sont prêtes, affichez les contrôles video.addEventListener ('loadeddata', this.initializeControls, false);
Si vous connaissez un peu de JavaScript, vous craignez peut-être de ne pas compenser Internet Explorer. Pour ceux qui ne le savent pas, IE8 et les versions antérieures ne reconnaissent pas addEventListener
. Au lieu de cela, de la manière habituelle, IE utilise ses propres attachEvent
. Cependant, tout cela change dans la version 9 du navigateur. Comme IE8 et ci-dessous ne comprennent pas la vidéo
élément, on peut ignorer le attachEvent
événement entièrement.
Quand le loadeddata
Si l'événement se déclenche, nous appelons la méthode "initializeControls" à créer. Dans une méthode d'objet, nous ne pouvons pas faire référence à "initializeControls" par lui-même. Nous devons d'abord faire référence à l'objet lui-même: d'où, this.initializeControls
.
Allons-y et créons cette méthode maintenant.
initializeControls: function () // Une fois toutes les méta-informations chargées, affiche les contrôles videoPlayer.showHideControls ();
Comme indiqué précédemment, si vous écrivez votre propre lecteur personnalisé, utilisez cette méthode pour effectuer toute procédure initiale supplémentaire. Pour l'instant, cette méthode appelle une autre méthode, showHideControls
. Cette nouvelle méthode affiche ou masque les contrôles lorsque l'utilisateur passe la souris sur la vidéo..
showHideControls: function () // Affiche et masque le lecteur vidéo. video.addEventListener ('mouseover', function () videoControls.style.opacity = 1;, false); videoControls.addEventListener ('mouseover', function () videoControls.style.opacity = 1;, false); video.addEventListener ('mouseout', function () videoControls.style.opacity = 0;, false); videoControls.addEventListener ('mouseout', function () videoControls.style.opacity = 0;, false);
Cette méthode associe quatre gestionnaires d’événements au lecteur vidéo et contrôle les éléments, représentés par le vidéo
et videoControls
variables, respectivement. Ce code est simple: lorsque vous survolez la vidéo avec la souris, modifiez l'opacité des contrôles vidéo en 1. À l'inverse, lorsque la souris est désactivée, masquez les contrôles de la vue. Ce code suppose également que, par défaut, dans notre feuille de style, le contrôle vidéo opacité
est défini sur none.
Rappelez-vous: dans la mesure du possible, déléguez toujours le style à notre fichier CSS, plutôt que de l'ajouter directement avec votre JavaScript. Outre les avantages en termes de performances et la réduction des reflux / repeints, cette pratique adhère correctement à la séparation de la présentation et de la logique. Cependant, de temps en temps, vous n'aurez pas d'autre choix que d'ajouter le style à votre fichier JavaScript et, dans ces cas, ce n'est pas grave..
Nous avons maintenant caché avec succès les contrôles par défaut, mais nous n’avons encore associé aucune logique à ces différents boutons personnalisés. C'est ce que nous devons faire ensuite.
Retour à la init
method et ajoute un appel à une nouvelle méthode.
// Lors de la lecture, les boutons de pause sont appuyés. this.handleButtonPresses ();
Vous êtes bien entendu libre de nommer ces méthodes comme vous le souhaitez, mais essayez au moins de les nommer de manière à ce qu'il soit facile de comprendre exactement le but de la fonction..
handleButtonPresses: function () // Lorsque vous cliquez sur le bouton de vidéo ou de lecture, lisez / mettez en pause la vidéo. video.addEventListener ('click', this.playPause, false); play.addEventListener ('click', this.playPause, false); // Lorsque le bouton de lecture est enfoncé, // passe au symbole "Pause". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # x2590; & # x2590;'; , faux); // Lorsque le bouton de pause est enfoncé, // passe au symbole "Play". video.addEventListener ('pause', function () play.title = 'Lecture'; play.innerHTML = '& # x25BA;';, false); // Une fois la vidéo terminée, mettez-la en pause. video.addEventListener ('terminé', function () this.currentTime = 0; this.pause ();, false);
Dans cette méthode, nous associons à nouveau une poignée de nouveaux événements disponibles au vidéo
élément: jouer
, pause
, et terminé
.
Gardez à l’esprit que, par exemple, le
jouer
L’événement ne se déclenche pas lorsque vous cliquez sur le bouton de lecture créé. Non, au contraire, il se déclenche lorsque la vidéo commence à être lue. C'est une distinction importante à retenir.
Afin de déclencher les événements énumérés ci-dessus, nous ajoutons un autre écouteur d'événements au bouton de lecture et écoutons lorsque l'utilisateur clique dessus..
// Lorsque le bouton de vidéo ou de lecture est cliqué, lisez / mettez en pause la vidéo. play.addEventListener ('click', this.playPause, false);
playPause: function () if (video.paused || video.ended) if (video.ended) video.currentTime = 0; video.play (); else video.pause ();
Parlons du code ci-dessus en termes généraux. Lorsque cette méthode a été appelée - dans notre cas, lorsque le bouton de lecture a été cliqué pour la première fois - a-t-elle été interrompue ou à la fin de la vidéo? Dans ce dernier cas, il est nécessaire de remettre à zéro la durée de la vidéo pour qu'elle puisse être lue depuis le début. Ensuite, nous devons jouer la vidéo: video.play ()
.
Maintenant, si la vidéo n'a pas été mise en pause ou à la fin, ce qui signifie que la lecture de la vidéo était en cours au moment où le bouton de lecture a été cliqué, nous devrions faire l'inverse et suspendre la vidéo: video.pause ()
.
le jouer pause
La méthode, détaillée ci-dessus, gère le processus de lecture ou de pause de la vidéo. Mais nous devons certainement informer l'utilisateur de ce que le bouton poussoir fait, n'est-ce pas? Absolument; Pour ce faire, nous allons basculer entre un code de caractère HTML "jouer" et "mettre en pause" chaque fois que le bouton est cliqué. Donc, essentiellement, ce seul bouton gère à la fois le jeu et la pause.
Si vous vous référez aux écouteurs d'événements depuis un moment, nous avons déjà ajouté cette fonctionnalité..
// Lorsque le bouton de lecture est enfoncé, // passe au symbole "Pause". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # x2590; & # x2590;'; , faux); // Lorsque le bouton de pause est enfoncé, // passe au symbole "Play". video.addEventListener ('pause', function () play.title = 'Lecture'; play.innerHTML = '& # x25BA;';, false);
Assez simple, non? Si vous appuyez sur le bouton de lecture, le Cliquez sur
cas de déclenchement du bouton de lecture, qui appelle video.play ()
. Cette méthode lit alors la vidéo et déclenche la jouer
un événement. le jouer
event modifie ensuite la valeur du bouton en un symbole de pause et met également à jour l'attribut title. Enfin, lorsque ce processus se reproduit, nous faisons le contraire.
Je l'ai mentionné dans le premier paragraphe de ce didacticiel: le support en plein écran est essentiel pour moi. Ajoutons cette fonctionnalité maintenant. Retournez à votre init ()
méthode, et, encore une fois, ajoutez un extrait au bas. Nous devons écouter lorsque ce bouton bascule plein écran que nous avons créé…
… Est cliqué. Quand c'est le cas, nous devrions soit basculer la vidéo en plein écran, ou l'inverse.
N'oublie pas:
fullScreenToggleButton
fait référence au bouton "plein écran".
// Lorsque le bouton plein écran est enfoncé… fullScreenToggleButton.addEventListener ("click", function () isVideoFullScreen? That.fullScreenOff (): that.fullScreenOn ();, true);
Attends une minute: c'est quoi cette
? Ça ne devrait pas être ce
? La réponse est non. Dans le contexte de l'événement click, ce
se réfère maintenant au bouton "plein écran", pas le lecteur vidéo
objet.
Pour remédier à cela, nous allons "mettre en cache" la valeur originale de ce
dans une variable, appelée cette
. Cela peut être ajouté au sommet de notre init ()
méthode.
init: function () // c'est égal à l'objet videoPlayer. var que = ceci;…
Ta da! Maintenant, nous pouvons encore faire référence à la lecteur vidéo
objet. En tant que tel, that.fullScreenOff
signifie ", accédez à la méthode appelée" fullScreenOff "qui est un enfant du lecteur vidéo
objet.
Il y a un problème. Comment détermine-t-on l'état actuel de la vidéo? Est-ce une taille normale ou une taille normale? Un moyen simple de gérer cette situation consiste à créer une variable appelée "isVideoFullScreen". Vous pouvez ajouter cette variable tout en haut de votre page, avec les autres. Par défaut, bien sûr, cette valeur doit être définie sur faux
.
fullScreenToggleButton = document.getElementById ("fullScreen"), // Boolean qui nous permet de "mémoriser" la taille actuelle du lecteur vidéo. isVideoFullScreen = false,
Ce booléen nous permet maintenant d’appeler correctement la fonction appropriée lorsque l’on clique sur le bouton "Plein écran"..
isVideoFullScreen? that.fullScreenOff (): that.fullScreenOn ();
À l’aide de l’opérateur ternaire, nous vérifions: "la vidéo est-elle actuellement en mode plein écran? Si c’est le cas, nous appelons fullScreenOff ()
. Sinon, nous appelons fullScreenOn ()
.
fullScreenOn: function () isVideoFullScreen = true; // Définit la nouvelle largeur en fonction de la largeur de la fenêtre video.style.cssText = 'position: fixed; width: '+ window.innerWidth +' px; hauteur: '+ window.innerHeight +' px; '; // Applique un nom de classe à la vidéo et aux contrôles, si le concepteur en a besoin… video.className = 'fullsizeVideo'; videoControls.className = 'fs-control'; fullScreenToggleButton.className = "contrôle fs-active"; // Ecoute la clé d'échappement. Si appuyé, ferme le plein écran. document.addEventListener ('keydown', this.checkKeyCode, false); , fullScreenOff: function () isVideoFullScreen = false; video.style.position = 'static'; video.className = "; fullScreenToggleButton.className =" control "; videoControls.className =";
Au sein de ces deux fonctions, nous modifions d’abord la valeur de isVideoFullScreen
, en conséquence. Ensuite, nous ajustons la taille de la vidéo, elle-même. cssText
nous permet de passer une chaîne de style à un élément. Dans ce cas, nous ne pouvons pas accomplir cette tâche directement dans notre feuille de style. En effet, les valeurs souhaitées sont dynamiques et dépendent de la taille de la fenêtre du navigateur du visiteur..
Utilisation
window.innerWidth
etwindow.innerHeight
pour récupérer la largeur et la hauteur de la fenêtre du navigateur.
Il est également judicieux d’appliquer des noms de classe spécifiques à l’écran en plein écran à nos éléments. De cette façon, si vous avez besoin d’ajouter un style approprié, vous avez maintenant un nom de classe à connecter..
En plus du bouton bascule plein écran, il est également assez courant de quitter le mode plein écran lorsque l'utilisateur appuie sur la touche Échap de son clavier. C'est une bonne commodité que nous devrions implémenter dans notre lecteur. Heureusement, c'est facile!
// Ecoute la clé d'échappement. Si appuyé, ferme le plein écran. document.addEventListener ('keydown', this.checkKeyCode, false);
Pour écouter les clics clés, nous utilisons le touche Bas
un événement. Alors que je pouvais passer une fonction anonyme en tant que second paramètre, ce bit de code pourrait être utilisé à plusieurs endroits. Et lorsque cela est vrai, le code doit être déplacé vers sa propre fonction, pour pouvoir être réutilisé. Nous l'appellerons, checkKeyCode
.
// Détermine si la touche d'échappement a été enfoncée. checkKeyCode: fonction (e) e = e || window.event; if ((e.keyCode || e.which) === 27) videoPlayer.fullScreenOff ();
Cette fonction est malheureusement plus déroutante qu’elle ne devrait l’être, en raison de problèmes liés à Internet Explorer. Je ne suis certes pas certain de la manière dont l’IE9 à venir gère l’objet événement. Par conséquent, nous allons toujours compenser les divergences entre la manière dont IE et les autres navigateurs modernes gèrent cet événement..
En dehors de tout ce qui est ennuyeux, ce code vérifie si la clé sur laquelle vous avez cliqué porte le code "27". Si tel est le cas, la touche "Echap" a été activée. Dans ce cas, vous pouvez quitter le mode plein écran via videoPlayer.fullScreenOff ()
.
Dernier point, mais non le moindre, nous devons suivre l'évolution de la vidéo. Ainsi, au fur et à mesure que la vidéo progresse, nous devons fournir un «nettoyeur» de progression qui permettra de suivre la vidéo. De plus, il permet à l'utilisateur de numériser rapidement la partie souhaitée de la vidéo..
C'est facile: quand la vidéo est en lecture! Donc, dans cet esprit, modifions notre jouer
code d'événement et appelez une fonction qui suivra la progression de la vidéo.
// Lorsque le bouton de lecture est enfoncé, // passe au symbole "Pause". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # x2590; & # x2590;'; // Commencer à suivre les progrès de la vidéo. videoPlayer.trackPlayProgress (); , faux);
// Toutes les 50 millisecondes, met à jour la progression de la lecture. trackPlayProgress: function () (function progressTrack () videoPlayer.updatePlayProgress (); playProgressInterval = setTimeout (progressTrack, 50);) ();
Ne laissez pas ce code vous effrayer. C'est simplement une fonction récursive qui nous permet d'appeler une méthode différente, updatePlayProgress ()
, toutes les cinquante millisecondes. Pourquoi ne pas utiliser setInterval
au lieu? Ceci est dû au fait setInterval
peut être méchant parfois. Sans entrer trop dans les détails qui dépassent la portée de ce tutoriel, setInterval
s'exécutera (dans ce cas) toutes les cinquante millisecondes, quelle que soit la longueur du code dans la fonction.
setInterval
est comme un conducteur dans le trafic heure de pointe qui refuse de marcher sur les pauses.
Donc, si possible, en combinant setTimeout
avec une fonction récursive est la solution la plus intelligente. Notez que nous assignons setTimeout
à une variable, playProgressInterval
, parce que nous devons effacer ce délai plus tard. Par conséquent, nous avons besoin d’une sorte d’identifiant.
Maintenant que nous avons spécifié que toutes les cinquante millisecondes, le updatePlayProgress
méthode devrait être appelée, créons-la maintenant.
updatePlayProgress: function () playProgressBar.style.width = ((video.currentTime / video.duration) * (progressHolder.offsetWidth)) + "px";
Bien que le code ci-dessus puisse sembler très déroutant au début, ce n'est pas si grave. Nous saisissons la barre de progression et mettons à jour sa largeur (toutes les 50 ms). Nous pouvons déterminer la largeur correcte en divisant l'emplacement actuel de la vidéo par la longueur de la vidéo - que nous pouvons calculer avec video.duration
. Cette valeur doit ensuite être multipliée par la largeur totale de notre support de progression, et le tour est joué!
Mais que se passe-t-il lorsque la vidéo est mise en pause par l'utilisateur? Nous ne voulons sûrement pas continuer cela setTimeout
. Bien sûr que non. En tant que tel, nous devrions créer une autre méthode, appelée stopPlayProgress
, et y faire référence lorsque l'événement pause est déclenché.
// Nous avons déjà ajouté cet événement. Nous ne le mettons à jour qu'avec un nouvel appel en bas. video.addEventListener ('pause', function () play.title = 'Play'; play.innerHTML = '& # x25BA;'; // La vidéo a été mise en pause, arrêtez le suivi des progrès. videoPlayer.stopTrackingPlayProgress ();, false )
// La vidéo a été arrêtée, alors arrêtez de mettre à jour la progression. stopTrackingPlayProgress: function () clearTimeout (playProgressInterval);
La dernière étape de ce didacticiel explique comment "balayer" la vidéo, c'est-à-dire lorsque l'utilisateur clique sur la barre de progression et fait défiler la vidéo de haut en bas. Je suis sûr que vous avez déjà effectué cette tâche vous-même à plusieurs reprises. Non non Non; ces choses sont faites automatiquement. Nous devons coder cette fonctionnalité.
Vite… retiens ton souffle.
videoScrubbing: function () progressHolder.addEventListener ("mousedown", function () videoPlayer.stopTrackingPlayProgress (); videoPlayer.playPause (); document.onmousemove = fonction (e) videoPlayer.setPlayProgress (e.pageX); progressHolder .onmouseup = function (e) document.onmouseup = null; document.onmousemove = null; video.play (); videoPlayer.setPlayProgress (e.pageX); videoPlayer.trackPlayProgress ();, true); , setPlayProgress: fonction (clickX) var newPercent = Math.max (0, Math.min (1, (clickX - this.findPosX (progressHolder))) / progressHolder.offsetWidth)); video.currentTime = newPercent * video.duration; playProgressBar.style.width = newPercent * (progressHolder.offsetWidth) + "px"; , findPosX: function (progressHolder) var curleft = progressHolder.offsetLeft; while (progressHolder = progressHolder.offsetParent) curleft + = progressHolder.offsetLeft; retour curleft;
… Et expirez. Prenons cet énorme bloc de code ligne par ligne.
videoPlayer.stopTrackingPlayProgress
pour effacer le délai d'attente que nous avons créé ci-dessus. jouer pause
méthode qui gérera, dans ce cas, la mise en pause de la vidéo.