A pesar de que la idea de un elemento HTML específico de video fue sugerida hace más de una década, ¡apenas estamos empezando a ver cómo esto se materializa! Olvídate de todo ese "HTML5 2012" mumbo-jumbo; la verdad es que puedes usar el vídeo
Elemento en tus proyectos ahora mismo! Solo debes tener en cuenta algunos requisitos antes de dar el paso..
document.createElement ('video')
. Por extraño que parezca, esto parece desencadenar la conciencia de IE. Sí, es bastante extraño, pero hemos llegado a esperar eso de Internet Explorer, ¿verdad? Para acelerar este proceso, Remy Sharp creó HTML5 Shiv, que también, por cierto, soluciona algunos problemas de impresión cuando se trabaja con elementos HTML5. Simplemente descargue el script y haga referencia a él en el cabeza
sección de su (s) documento (s).ogg
formato, mientras que los navegadores Webkit pueden renderizar mp4
videos De hecho, esto es una simplificación excesiva; Sin embargo, esto hará por el momento. Sin embargo, basta con decir que se admiten más tipos de video, incluido el códec V8 de código abierto de Google.. Al igual que con cualquier proyecto, nuestro primer paso es crear el margen de beneficio necesario para nuestro proyecto..
Reproductor de video HTML5 personalizado Video HTML5
Primero, encuentra algunos videos de muestra para trabajar. El video de código abierto "Big Bunny Buck" tipo Pixar es lo que usaré. Estoy seguro de que ya lo has visto en uso en la web. Ver esta marca en el navegador podría dejarte con un signo de interrogación sobre tu cabeza.
Eh ¿Eso es? Simplemente parece una imagen. ¿Cuál es el problema? Bueno, por defecto, esto es todo lo que hemos solicitado. Luego tenemos que especificar si mostrar o no los controles, mostrar un póster, etc. Hagamos eso ahora; revisa tu vídeo
elemento, como asi:
Desde el principio, notamos que no hay citas en torno a los atributos. Como resultado, no son necesarios. Si bien hace años, se consideraba una mala práctica excluirlos, este ya no es el caso. En este punto, solo se trata de preferencias personales. Entonces, si te sientes más cómodo al agregarlos, entonces, por todos los medios, hazlo.
Obviamente no hacemos qué usar los controles predeterminados del navegador. Como tal, debemos implementar nuestros propios controles de marcado. Antes de que progresemos, es posible que acabe de preguntarse: "¿Cuál es el punto de agregar el controles
atributo en absoluto? La respuesta es porque debemos considerar y compensar el hecho de que JavaScript podría estar deshabilitado en la computadora del usuario. En esos casos, si no hubiéramos agregado el controles
Atributo, solo verían lo que parece ser una imagen..
Siempre considere la posibilidad de que JavaScript esté deshabilitado..
los div
con un id de "videoControls" es donde agregaremos los botones y el logotipo necesarios. Un pequeño truco ingenioso es el uso de "& # x25BA;" para crear el botón de reproducción. No te preocupes demasiado por el div "progreso"; revisaremos esta sección con más detalle más adelante en este tutorial. La respuesta corta es que este es el contenedor para nuestra barra de progreso. Por último, añadimos un botón
que cambiará la funcionalidad de pantalla completa, así como el logotipo de Tuts +.
No te preocupes aunque parece que ahora hemos creado un segundo conjunto de controles (y sin estilo al respecto), eventualmente eliminaremos los controles predeterminados con JavaScript. No obstante, la captura de pantalla anterior debe coincidir con su propia vista previa, si está siguiendo.
Con el marcado completo, ahora podemos pasar a la parte divertida. Crea una nueva carpeta, llamada "js", y agrega un nuevo archivo: videoPlayer.js
. A continuación, seamos buenos niños y niñas y envolvamos nuestro código dentro de una función anónima que se invoque a sí misma, para evitar la creación de variables globales innecesarias..
(función (ventana, documento) (este, documento))
Puede eliminar los argumentos si lo desea, es una pequeña mejora con dos ventajas:
esta
(el objeto de la ventana global) y documento
, evitamos que el motor de JavaScript tenga que filtrar y rastrear esos objetos. Esto puede ser una gran conveniencia para proyectos más grandes, pero ofrece un beneficio de rendimiento muy pequeño. ventana
y documento
Ahora se puede representar a través de algo como una
y segundo
. A continuación, continuemos manteniendo nuestro código lo más limpio posible creando un reproductor de video
Objeto que contendrá todos nuestros métodos. También crearemos un en eso
Método que se llamará inmediatamente cuando se carga la página..
(función (ventana, documento) var videoPlayer = init: function () ; videoPlayer.init (); (este, documento))
Como ciertamente estaremos manipulando elementos en la página, avancemos y hagamos referencia a la ubicación de ellos dentro de las variables. Justo antes de que declaremos la variable "videoPlayer", prepend:
var video = document.getElementsByTagName ('video') [0], videoControls = document.getElementById ('videoControls'), play = document.getElementById ('play'), progressContainer = document.getElementByd ("progress"), progressHolder = document.getElementById ("progress_box"), playProgressBar = document.getElementById ("play_progress"), fullScreenToggleButton = document.getElementById ("fullScreen");
Si está trabajando a lo largo (y espero que lo esté), tómese un tiempo para aprender exactamente a qué se refieren estas variables. Vuelve a tu marcado, si es necesario. Tomamos el elemento de video, el control de video div, el botón de reproducción, el botón de alternar de pantalla completa y los tres divs de progreso. "Almacenamos en caché" la ubicación de estos elementos porque no hay razón para atravesar el DOM innecesariamente cada vez que necesitamos acceder a uno de estos elementos.!
En eso
Método Vamos a empezar a escribir un código real. Dentro de en eso
método, pegar en el siguiente fragmento de código:
init: function () // esto es igual al objeto videoPlayer. var que = esto; // Activador CSS útil para JS. document.documentElement.className = 'js'; // Deshazte de los controles predeterminados, porque usaremos los nuestros. video.removeAttribute ('controles'); // Cuando los metadatos estén listos, muestre los controles video.addEventListener ('loadeddata', this.initializeControls, false);
Una forma clara de personalizar los elementos según si JavaScript está habilitado es aplicando una clase de "js" a la documentElement
, o la html
elemento.
// Activador CSS útil para JS. document.documentElement.className = 'js';
Esto nos permite luego escribir CSS como:
.js #container / * este estilo solo se procesa si JS está habilitado * /
¿Recuerda el problema con los dos conjuntos de controles de video? Vamos a remediar eso ahora. Esta es una fácil; simplemente usaremos el removeAttribute
método, y deshacerse de controles
.
// Deshazte de los controles predeterminados, porque usaremos los nuestros. video.removeAttribute ('controles');
Agreguemos ahora nuestro primer evento HTML5: datos cargados
. Este evento se activa cuando el navegador ha terminado de cargar los metadatos del video. Este es un excelente lugar para realizar cualquier procedimiento inicial, como mostrar controles personalizados.
// Cuando los metadatos estén listos, muestre los controles video.addEventListener ('loadeddata', this.initializeControls, false);
Si conoce un poco de JavaScript, es posible que le preocupe que no estamos compensando por Internet Explorer. Para aquellos que no lo saben, IE8 y anteriores no reconocen addEventListener
. En cambio, en la forma en que se ha acostumbrado, IE usa su propia adjuntar
. Sin embargo, todo eso está cambiando en la versión nueve del navegador. Como IE8 y abajo no entienden el vídeo
Elemento, podemos ignorar el adjuntar
evento enteramente.
Cuando el datos cargados
evento se activa, llamamos al método "initializeControls" que aún no se ha creado. Dentro de un método de objeto, no podemos referirnos a "initializeControls" por sí mismo. Primero debemos hacer referencia al objeto en sí: por lo tanto, this.initializeControls
.
Sigamos adelante y creamos ese método ahora..
initializeControls: function () // Cuando toda la información meta se haya cargado, muestre los controles videoPlayer.showHideControls ();
Como se mencionó anteriormente, si escribe su propio reproductor personalizado, use este método para realizar cualquier procedimiento inicial adicional. Por ahora, este método llamará a otro método., showHideControls
. Este nuevo método mostrará u ocultará los controles cuando el usuario se desplace sobre el video.
showHideControls: function () // Muestra y oculta el reproductor de video. 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);
Este método conecta cuatro controladores de eventos al reproductor de video y controla los elementos, representados por el vídeo
y videoControles
variables, respectivamente. Este código es simple: cuando pasa el mouse sobre el video, cambia la opacidad de los controles de video a 1. Inversamente, cuando está apagado, oculte los controles de la vista. Este código también supone que, de forma predeterminada, dentro de nuestra hoja de estilo, el control de video opacidad
se establece en ninguno.
Recuerde: cuando sea posible, siempre delegue el estilo a nuestro archivo CSS, en lugar de agregarlo directamente con su JavaScript. Además de los beneficios de rendimiento y la reducción de reflujos / repintados, esta práctica se adhiere correctamente a la separación de la presentación de la lógica. Sin embargo, de vez en cuando, no tendrá más opción que agregar el estilo dentro de su archivo JavaScript y, en esos casos, está bien..
Ahora hemos ocultado con éxito los controles predeterminados, pero aún no hemos conectado ninguna lógica a estos diversos botones personalizados. Eso es lo que debemos hacer a continuación..
Volver a la en eso
método, y añadir una llamada a un nuevo método.
// Durante la reproducción, se pulsan los botones de pausa. this.handleButtonPresses ();
Usted es, por supuesto, libre de nombrar estos métodos como desee, pero al menos trate de nombrarlos de tal manera que sea fácil entender exactamente cuál es el propósito de la función..
handleButtonPresses: function () // Cuando se hace clic en el botón de video o de reproducción, reproducir / pausar el video. video.addEventListener ('clic', this.playPause, false); play.addEventListener ('clic', this.playPause, false); // Cuando se presiona el botón de reproducción, // cambia al símbolo "Pausa". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # x2590; & # x2590;'; , falso); // Cuando se presiona el botón de pausa, // cambia al símbolo "Play". video.addEventListener ('pause', function () play.title = 'Play'; play.innerHTML = '& # x25BA;';, false); // Cuando el video haya concluido, pause. video.addEventListener ('finalizado', función () this.currentTime = 0; this.pause ();, false);
Dentro de este método, nuevamente adjuntamos un puñado de eventos nuevos que están disponibles para el vídeo
elemento: jugar
, pausa
, y terminó
.
Tenga en cuenta que, por ejemplo, el
jugar
El evento no se dispara al hacer clic en el botón de reproducción que creamos. No, en cambio, se dispara cuando el video comienza a reproducirse. Esa es una distinción importante para recordar..
Para activar los eventos enumerados anteriormente, agregamos otro detector de eventos al botón de reproducción y escuchamos cuando el usuario hace clic en él..
// Cuando se hace clic en el botón de video o reproducción, reproducir / pausar el video. play.addEventListener ('clic', this.playPause, false);
playPause: function () if (video.paused || video.ended) if (video.ended) video.currentTime = 0; video.play (); else video.pause ();
Vamos a hablar a través del código anterior en general, hablar. Cuando se llamó a este método, en nuestro caso, cuando se hizo clic por primera vez en el botón de reproducción, ¿se pausó o al final del video? Si es lo último, necesitamos restablecer la hora del video nuevamente a 0, para que pueda volver a reproducirse desde el principio. A continuación, tenemos que reproducir el video: video.play ()
.
Ahora, si el video no se pausó o al final, lo que significa que el video se estaba reproduciendo cuando se hizo clic en el botón de reproducción, deberíamos hacer lo contrario, y pausar el video en su lugar: video.pause ()
.
los reproducir pausar
El método, detallado anteriormente, maneja el proceso de reproducción o pausa del video. Pero, ciertamente, debemos proporcionar al usuario algunos comentarios sobre lo que hace el pulsador del botón, ¿verdad? Seguro; para hacerlo, cambiaremos entre un código de caracteres HTML "reproducir" y "pausar" cada vez que se haga clic en el botón. Así que, esencialmente, este botón maneja tanto la reproducción como la pausa..
Si va a consultar a los oyentes del evento hace un momento, ya hemos agregado esta funcionalidad..
// Cuando se presiona el botón de reproducción, // cambia al símbolo "Pausa". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # x2590; & # x2590;'; , falso); // Cuando se presiona el botón de pausa, // cambia al símbolo "Play". video.addEventListener ('pause', function () play.title = 'Play'; play.innerHTML = '& # x25BA;';, false);
Bastante simple, ¿verdad? Si se presiona el botón de reproducción, hacer clic
Se dispara el evento del botón de reproducción, que llama. video.play ()
. Este método luego reproduce el video y activa el jugar
evento. los jugar
evento luego cambia el valor del botón a un símbolo de pausa, y también actualiza el atributo del título. Finalmente, cuando este proceso vuelve a ocurrir, hacemos lo contrario..
Lo mencioné en el párrafo inicial de este tutorial: el soporte de pantalla completa es una necesidad para mí. Vamos a añadir esa funcionalidad ahora. Volver a su en eso()
Método, y, una vez más, agregar un fragmento de código en la parte inferior. Necesitamos escuchar cuando ese botón de alternar de pantalla completa que creamos ...
... se hace clic. Cuando sea así, deberíamos cambiar el video a pantalla completa o lo contrario..
No olvides
fullScreenToggleButton
se refiere al botón "pantalla completa".
// Cuando se presiona el botón de pantalla completa ... fullScreenToggleButton.addEventListener ("click", function () isVideoFullScreen? That.fullScreenOff (): that.fullScreenOn ();, true);
Espera un minuto: que es ese
? No deberia ser esta
? La respuesta es no. Dentro del contexto del evento clic., esta
ahora se refiere al botón "pantalla completa", no al botón reproductor de video
objeto.
Para remediar esto, "guardaremos en caché" el valor original de esta
dentro de una variable, llamada ese
. Esto se puede agregar a la parte superior de nuestra en eso()
método.
init: function () // esto es igual al objeto videoPlayer. var que = esto;…
Ta da! Ahora, podemos referirnos nuevamente a la reproductor de video
objeto. Como tal, that.fullScreenOff
significa "acceder al método llamado" fullScreenOff "que es un elemento secundario del reproductor de video
objeto.
Hay un problema ¿Cómo determinamos el estado actual del video? ¿Es de tamaño completo o regular? Una forma fácil de manejar esta situación es crear una variable, llamada "isVideoFullScreen". Puedes agregar esta variable en la parte superior de tu página, junto con las demás. Por defecto, por supuesto, este valor se debe establecer en falso
.
fullScreenToggleButton = document.getElementById ("fullScreen"), // Boolean que nos permite "recordar" el tamaño actual del reproductor de video. isVideoFullScreen = false,
Este booleano ahora nos permite llamar correctamente a la función apropiada cuando se hace clic en el botón "Pantalla completa".
isVideoFullScreen? that.fullScreenOff (): that.fullScreenOn ();
Usando el operador ternario, verificamos: "¿el video está actualmente en modo de pantalla completa? Si es así, llamamos fullScreenOff ()
. De lo contrario, llamamos fullScreenOn ()
.
fullScreenOn: function () isVideoFullScreen = true; // Establecer un nuevo ancho de acuerdo con el ancho de la ventana video.style.cssText = 'position: fixed; ancho: '+ window.innerWidth +' px; altura: '+ window.innerHeight +' px; '; // Aplique un nombre de clase al video y los controles, si el diseñador lo necesita ... video.className = 'fullsizeVideo'; videoControls.className = 'fs-control'; fullScreenToggleButton.className = "fs-active control"; // Escucha la clave de escape. Si se presiona, cierre la pantalla completa. document.addEventListener ('keydown', this.checkKeyCode, false); , fullScreenOff: function () isVideoFullScreen = false; video.style.position = 'static'; video.className = "; fullScreenToggleButton.className =" control "; videoControls.className =";
Dentro de estas dos funciones, primero cambiamos el valor de isVideoFullScreen
, en consecuencia. A continuación, ajustamos el tamaño del video, en sí.. cssText
nos permite pasar una cadena de estilo a un elemento. En este caso, no podemos realizar esta tarea directamente desde nuestra hoja de estilos. Esto se debe a que los valores deseados son dinámicos y dependerán del tamaño de la ventana del navegador del visitante..
Utilizar
window.innerWidth
ywindow.innerHeight
para recuperar el ancho y alto de la ventana del navegador.
También es una buena práctica aplicar nombres de clase específicos de pantalla completa a nuestros elementos. De esa manera, si necesita agregar un estilo apropiado, ahora tiene un nombre de clase para enganchar a.
Además del botón de alternar de pantalla completa, también es bastante común dejar el modo de pantalla completa cuando el usuario presiona la tecla de escape en su teclado. Es una buena conveniencia, y es una que debemos implementar en nuestro jugador. Afortunadamente es facil!
// Escucha la clave de escape. Si se presiona, cierre la pantalla completa. document.addEventListener ('keydown', this.checkKeyCode, false);
Para escuchar clics clave, usamos el keydown
evento. Si bien podría pasar una función anónima como segundo parámetro, este bit de código podría usarse en múltiples lugares. Y cuando esto sea cierto, el código debe reubicarse en su propia función, para su reutilización. Lo llamaremos, checkKeyCode
.
// Determina si la tecla de escape fue presionada. checkKeyCode: function (e) e = e || window.event; if ((e.keyCode || e.which) === 27) videoPlayer.fullScreenOff ();
Desafortunadamente, esta función es más confusa de lo que debería ser, debido a problemas de Internet Explorer. Es cierto que no estoy seguro de cómo el próximo IE9 maneja el objeto de evento, por lo que, por el momento, seguiremos compensando las discrepancias entre la forma en que IE y los otros navegadores modernos manejan el objeto de evento..
Dejando de lado las cosas aburridas, este código verifica si la clave en la que se hizo clic tiene un código de "27". Si lo hace, entonces se presionó la tecla "Escape", en cuyo caso podemos salir de pantalla completa, a través de videoPlayer.fullScreenOff ()
.
Por último, pero no menos importante, tenemos que seguir el progreso del video. Entonces, a medida que el video progresa, debemos proporcionar un "scrubber" de progreso que ayude a rastrear el video. Además, le permite al usuario escanear rápidamente a la parte deseada del video.
Eso es fácil: cuando el video se está reproduciendo! Así que, con eso en mente, modifiquemos nuestra jugar
código de evento, y llame a una función que rastreará el progreso del video.
// Cuando se presiona el botón de reproducción, // cambia al símbolo "Pausa". video.addEventListener ('play', function () play.title = 'Pause'; play.innerHTML = '& # x2590; & # x2590;'; // Comenzar a seguir el progreso del video. videoPlayer.trackPlayProgress (); , falso);
// Cada 50 milisegundos, actualiza el progreso del juego. trackPlayProgress: function () (function progressTrack () videoPlayer.updatePlayProgress (); playProgressInterval = setTimeout (progressTrack, 50);) ();
No dejes que este código te asuste. Es simplemente una función recursiva que nos permite llamar a un método diferente, updatePlayProgress ()
, cada cincuenta milisegundos. ¿Por qué no usar setInterval
¿en lugar? Esto es porque setInterval
puede ser desagradable a veces. Sin entrar en demasiados detalles que excede el alcance de este tutorial., setInterval
se ejecutará (en este caso) cada cincuenta milisegundos, independientemente del tiempo que tome el código dentro de la función.
setInterval
es como un conductor en el tráfico de hora punta que se niega a pisar los descansos.
Entonces, cuando sea posible, combinando setTimeout
Con una función recursiva es la solución más inteligente. Tenga en cuenta que asignamos setTimeout
a una variable, playProgressInterval
, Porque necesitamos aclarar más tarde este timeout. Por lo tanto, necesitamos algún tipo de identificación para enganchar en.
Ahora que hemos especificado que, cada cincuenta milisegundos, el updatePlayProgress
El método debería ser llamado, creémoslo ahora..
updatePlayProgress: function () playProgressBar.style.width = ((video.currentTime / video.duration) * (progressHolder.offsetWidth)) + "px";
Aunque el código de arriba puede parecer súper confuso al principio, no es tan malo. Tomamos la barra de progreso y actualizamos su ancho (cada 50 ms). Podemos determinar el ancho correcto dividiendo la ubicación actual del video, por la longitud del video, que podemos calcular con video.duration
. Este valor se debe multiplicar por el ancho total de nuestro titular de progreso, y listo!
Pero, ¿qué pasa si el video es pausado por el usuario? Seguramente no queremos continuar con esto. setTimeout
. Por supuesto no. Como tal, deberíamos crear otro método, llamado stopPlayProgress
, y consúltelo cuando se active el evento de pausa..
// Ya hemos añadido este evento. Solo lo estamos actualizando con una nueva llamada en la parte inferior. video.addEventListener ('pause', function () play.title = 'Play'; play.innerHTML = '& # x25BA;'; // El video fue pausado, detiene el progreso del seguimiento. videoPlayer.stopTrackingPlayProgress ();, false );
// El video fue detenido, así que deja de actualizar el progreso. stopTrackingPlayProgress: function () clearTimeout (playProgressInterval);
El último paso que cubriremos en este tutorial detalla cómo "arrastrar" el video, es decir, cuando el usuario hace clic en la barra de progreso y se desplaza hacia arriba y hacia abajo en el video. Estoy seguro de que has realizado esta tarea tú mismo en múltiples ocasiones. No no no; estas cosas se hacen automáticamente Tenemos que codificar esa funcionalidad..
Rápido… aguanta la respiración.
videoScrubbing: function () progressHolder.addEventListener ("mousedown", function () videoPlayer.stopTrackingPlayProgress (); videoPlayer.playPause (); document.onmousemove = function (e) videoPlayer.setPlayProgress (e.pageX); .onmouseup = function (e) document.onmouseup = null; document.onmousemove = null; video.play (); videoPlayer.setPlayProgress (e.pageX); videoPlayer.trackPlayProgress ();, true); , setPlayProgress: function (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; retorno curleft;
... y espira. Tomemos este enorme grupo de código línea por línea.
videoPlayer.stopTrackingPlayProgress
para despejar el tiempo de espera que creamos arriba. reproducir pausar
Método que manejará, en este caso, pausando el video.. setPlayProgress
método.