Introducción al vídeo en HTML5
Bruce Lawson, Patrick H. Lauke. 11 de febrero de 2010. Publicado en: css, canvas, accesibilidad, html5, multimedia, vídeo, opera 10.50, web abierta
Introducción
Hace mucho tiempo, en una galaxia que ahora parece muy lejana, el multimedia en la web se limitaba a canciones MIDI de sonido metálico y GIF animados. A medida que crecía el ancho de banda y mejoraban las tecnologías de compresión la música MP3 suplantó al MIDI y el vídeo de verdad comenzó a ganar terreno. Todo tipo de reproductores propietarios plantearon un verdadero combate —Real Player, Windows Media Player, etc— hasta que uno emergió como vencedor en 2005: Adobe Flash. Esto fue en gran parte debido a la ubicuidad de su plug-in y el hecho de que era el mecanismo de distribución elegido por YouTube. Flash se ha convertido en el estándar de facto para la distribuciónn de vídeo en la web.
Una de las novedades más emocionantes de HTML 5 es la inclusión del elemento <video>
, que permite a los desarrolladores incluir vídeo directamente en sus páginas sin necesidad de una solución basada en plug-ins. Opera propuso el elemento <video>
estándar como parte de HTML5 en 2007, e hizo su debut oficial en Opera 10.50.
En este artículo se da una introducción a <video>
y algunas de sus APIs asociadas. Veremos por qué el soporte de vídeo nativo en los navegadores es importante, daremos un repaso al marcado del elemento y resumiremos las formas más importantes para controlar el vídeo a través de JavaScript.
¿Por qué necesitamos un elemento <video>
?
Hasta ahora, si querías incluir vídeo en una página web, tenías que bregar con un marcado bastante críptico. He aquí un ejemplo, tomado directamente de YouTube:
<object width="425" height="344">
<param name="movie"
value="http://www.youtube.com/v/9sEI1AUFJKw&hl=en_GB&fs=1&"></param>
<param name="allowFullScreen"
value="true"></param>
<param name="allowscriptaccess"
value="always"></param>
<embed src="http://www.youtube.com/v/9sEI1AUFJKw&hl=en_GB&fs=1&"
type="application/x-shockwave-flash" allowscriptaccess="always"
allowfullscreen="true" width="425"
height="344"></embed>
</object>
En primer lugar, tenemos un elemento <object>
, un contenedor genérico de "objetos extraños", para incluir la película Flash. Para evitar inconsistencias entre navegadores, también incluimos un elemento de reserva <embed>
como contenido de repuesto y duplicamos la mayoría de los parámetros del <object>
. El código resultante es torpe y no muy legible, y tiene otros problemas: el contenido del plugin no interactúa demasiado bien con las otras tecnologías en la página y tiene problemas inherentes de accesibilidad (más sobre esto después).
Anatomía del elemento <video>
En comparación con la complicada construcción necesaria para incluir Flash en la página, el marcado básico necesario para <video>
en HTML5 es refrescantemente sencillo:
<video src=turkish.ogv
width=320
height=240
controls
poster=turkish.jpg>
</video>
Nótese que en nuestro ejemplo nos aprovechamos de la sintaxis más relajada de HTML5: no es necesario entrecomillar los valores de atributos y se pueden usar atributos simples booleanos como autoplay
como palabras sueltas. Si se prefiere, se puede, por supuesto, ajustarse también a la sintaxis XHTML controls="controls"
y entrecomillar todos los valores de los atributos. Obviamente, tiene sentido elegir el estilo de programación que más convenga y aferrarse a él, por coherencia y facilidad de mantenimiento. En XHTML5, debe utilizarse la sintaxis de XHTML (y también deben servirse las páginas como XML con el tipo MIME correcto, que en la actualidad no funciona en Internet Explorer).
Los atributos del elemento <video>
que hemos utilizado en nuestro código de muestra son bastante autoexplicativos :
src
- La fuente del elemento, con la dirección URL del archivo de vídeo.
width
yheight
- Al igual que con los elementos
img
, se pueden establecer explícitamente las dimensiones del vídeo. De lo contrario, el elemento usará como valor por defecto el ancho y alto intrínsecos del archivo de vídeo. Si se especifica una pero no la otra, el navegador modificará el tamaño de la dimensión no especificada para preservar la relación de aspecto del vídeo. controls
- Si este atributo booleano está presente, el navegador mostrará sus controles de vídeo nativos para la reproducción y el volumen. Si se omite, el usuario sólo verá el primer fotograma (o la imagen
poster
especificada) y no será capaz de reproducir el vídeo, a menos que se dispare la película desde algún fragmento de JavaScript o crees tus propios controles personalizados, tal y como explicaremos más adelante en este artículo. poster
- El atributo
poster
señala una imagen que el navegador usará mientras se descarga el vídeo, o hasta que el usuario indique que el vídeo debe reproducirse. Si no se incluye, se usará el primer fotograma del vídeo.
Para los navegadores web que no admiten actualmente <video>
, se puede incluir contenido alternativo. Como mínimo podría incluirse un texto y un enlace al archivo de vídeo en sí, de modo que los usuarios puedan descargar y reproducirlo con la aplicación que deseen:
<video src=turkish.ogv
width=320
height=240
controls
poster=turkish.jpg>
Download the <a href=video.ogg>Turkish dancing masterclass video</a>
</video>
Así, sin más interludios, puedes echar un vistazo al vídeo de una clase de danza turca, implementando usando exclusivamente la potencia del elemento <video>
nativo.
Hay más atributos que no hemos cubierto en nuestros ejemplos. Son:
autoplay
- Indica al navegador que debe iniciarse la reproducción del vídeo de forma automática. Utiliza este atributo con cuidado, ya que puede ser muy molesto, si no francamente problemático, especialmente para los usuarios con ayudas técnicas como lectores de pantalla o los que usan conexiones de bajo ancho de banda (por ejemplo, desde un dispositivo móvil).
autobuffer
- Si estás bastante seguro de que el usuario querrá activar el vídeo (por ejemplo, porque ha navegado específicamente hasta él y el vídeo es la única razón para estar en la página), pero no deseas utilizar
autoplay
, puedes establecer la booleanaautobuffer
. Esta pide al navegador que empiece a descargar al archivo inmediatamente, anticipando que el usuario va a reproducir el vídeo. (Esta parte de la especificación se encuentra actualmente en proceso de cambio, por lo que no se ha implementado en Opera hasta el momento) loop
- El atributo
loop
(bucle) es otro booleano. Como es de imaginar, pone el vídeo en un bucle infinito. (En la actualidad esto no se ha implementado en Opera)
Códecs: la mosca en la sopa
Por el momento, la versión oficial de consumo de Opera sólo admite el códec de vídeo Ogg Theora, un formato abierto de compresión de vídeo de la fundación Xiph.org libre de licencias.
Firefox y Chrome también soportan Theora. Sin embargo, Safari no lo hace, prefiriendo en su lugar dar soporte nativo para el códec H.264 (que también es compatible con Chrome). Microsoft también ha anunciado soporte para <video>
distribuido con H.264. Como se puede imaginar, esto provoca algunos problemas en términos de la necesidad de hacer que los vídeos estén disponibles en diferentes formatos para diferentes navegadores.
En un intento por solucionar este problema, Google ha publicado recientemente el códec de vídeo VP8 y el formato de contenedor WebM en condiciones libres de royalties, con el objetivo de ofrecer un formato de vídeo abierto de alta calidad disponible para los diferentes navegadores y plataformas. Así lo anunció públicamente en la conferencia Google I/O de 2010.
En el día del anuncio, Opera lanzó una versión experimental con soporte para WebM. Esta característica es ahora parte de la funcionalidad básica de Opera 10.60 y de todas nuestras futuras versiones del navegador de escritorio.
Volviendo a nuestro ejemplo, vamos a codificar el vídeo dos veces —una vez en Theora y otra en H.264—, añadiremos elementos <source>
alternativos con los atributos type
apropiados al vídeo y dejaremos que el navegador descargue el formato que sea capaz de mostrar. Nótese que en este caso no indicamos un atributo src
en el propio elemento <video>
:
<video width=320 height=240 controls poster=turkish.jpg>
<source src=turkish.ogv type=video/ogg>
<source src=turkish.mp4 type=video/mp4>
Download the <a href=video.ogg>Turkish dancing masterclass video</a>
</video>
Aquí está nuestra clase de danza turca con fuentes tanto .ogv como .mp4.
El tipo de archivo MP4 también puede ser reproducido por el plug-in de Flash, por lo que ambos pueden ser usados en combinación como contenido de emergencia para las versiones actuales de Internet Explorer y las versiones antiguas de todos los navegadores. Véase la ingeniosa aplicación por parte de Kroc Camen de esta técnica en su artículo Video for everyone!, en el que integra como un doctor Frankenstein los antiguos object
y embed
en la parte de contenido alternativo del elemento <video>
.
Por supuesto, si los navegadores que no soportan el elemento <video>
recurren a usar plug-ins como QuickTime o Flash, volvemos a estar como al principio, y no podremos beneficiarnos de ninguna de las nuevas características y mejoras que esbozaremos a continuación. "¿De qué sirve entonces?", te puedes preguntar. Diríamos que esta es una solución transitoria, hasta que el soporte nativo de vídeo llegue todos los principales navegadores y se llegue a un acuerdo sobre formatos. Es un caso de degradación grácil: puede que a los usuarios les llegue una versión un tanto recortada de la página, pero al menos serán capaces de ver las películas.
Ciudadano de primera en la Web
Ya hemos visto que el marcado del nuevo elemento <video>
de HTML5 es un orden de magnitud más legible y comprensible, en comparación con lo que actualmente hay que hacer para incorporar películas Flash a nuestro marcado. Pero independientemente de lo horrible de la vieja forma de codificación, en la mayoría de los casos funciona, ¿no? Entonces ¿por qué íbamos a querer alejarnos de este enfoque de distribución de vídeo a través de un plug-in como Flash?
La principal ventaja del elemento <video>
de HTML5 es que finalmente el vídeo se convierte en ciudadano de pleno derecho en la Web, en lugar de ser relegado al interior de un object o del elemento no válido embed (a pesar de que ahora valida en HTML5). Vamos a ampliar en algunas de las ventajas.
Accesibilidad por teclado incorporada
Uno de los grandes problemas no resueltos de la utilización de Flash es la accesibilidad por teclado. Con la excepción de Internet Explorer para Windows, en general no hay ninguna manera de que un usuario pueda saltar sólo con el teclado hasta dar foco a una película Flash. E incluso si estos usuarios se las arreglan para conseguirlo (utilizando tecnologías de asistencia adicional), no hay manera fácil para saltar de nuevo fuera de él (a menos que se agregue código ActionScript adicional a la película para establecer mediante programación el foco del navegador fuera del plugin, en la página). Por el contrario, como el navegador es el responsable directo del elemento <video>
, puede manejar los controles de la película como si fueran botones normales de una página web e incluirlos en el orden normal de tabulación.
El soporte de teclado para el vídeo nativo no ha sido implementado en la actualidad en todos los navegadores... sin embargo, ya funciona bien en Opera 10.50 y superiores.
<video>
interactúa bien con el resto de la página
En términos simples, cuando incluyes un plug-in en una página reservas un área de dibujo que el navegador delega en el plugin. Por lo que al navegador se refiere, el área del plug-in es una caja negra: el navegador no procesa ni interpreta nada de lo pase allí.
Normalmente esto no es un problema, pero pueden surgir inconvenientes cuando el diseño se solapa con el área de dibujo del plug-in. Imagina, por ejemplo, un sitio con una película Flash pero que también tiene JavaScript o menús desplegables basados en CSS que deben desplegarse por encima de la película. Por defecto, el área de dibujo del plugin está por encima de la página web, lo que significa que los menús, extrañamente, aparecerán detrás de la película. Un efecto antiestético similar ocurre si la página utiliza lightboxes1: cualquier película Flash parecería flotar por encima de la página atenuada. Esta es la razón por la que la mayoría de scripts lightbox existentes tiende a cortar por lo sano con la cuestión, eliminando en primer lugar cualquier objeto plugin de la página antes de activar la superposición y volviendo a introducirlos al final.
En el caso específico de los plug-ins Flash, los desarrolladores pueden solucionar este problema de presentación añadiendo el atributo wmode='opaque'
al elemento <object>
y el equivalente <param name='wmode' value='opaque'>
al elemento <embed>
. Sin embargo, esto también hace que el plug-in sea completamente inaccesible para los usuarios con lectores de pantalla, por lo que es mejor evitarlo.
También pueden surgir problemas y peculiaridades si la página sufre cambios dinámicos de layout. Si las dimensiones del área de dibujo del plugin cambian de tamaño, esto a veces puede tener efectos imprevistos: puede que una película en reproducción no cambie de tamaño, sino que simplemente se recorte o muestre espacio en blanco extra.
Con el elemento <video>
nativo, es el propio navegador el que se ocupa de mostrarlo. Así, <video>
se comporta exactamente igual que cualquier otro elemento en el diseño de la página. Se puede colocar, flotar, sobreponer o cambiar de tamaño dinámicamente, sin hacks adicionales. Incluso es posible lograr efectos interesantes, tales como vídeo semi-transparente, simplemente mediante el establecimiento de la opacidad del elemento a través de CSS.
Nos espera todo un nuevo mundo de vídeos de lindos gatitos. No tengo gatitos a mano, pero sí tengo el mejor sucedáneo: niños, así que voy a usar un par de videos con niños para fines de demostración.
Estilos de vídeo con CSS
Ahora que <video>
es parte del conjunto de tecnologías de la web abierta, podemos usar CSS para dar estilo al elemento de forma fiable. Como una simple demostración de lo que ahora se puede lograr, vamos a aplicar transiciones CSS al vídeo de danza turca que modifiquen sus dimensiones una vez que hagamos :hover:
o :focus:
. (Puede lee el tutorial de Opera de transiciones CSS3 y transformaciones 2D.)
Combinar vídeo y canvas
A medida que el navegador se va ocupando de mostrar y procesar vídeo, se pueden superponer y combinar fácilmente otros elementos sobre este. En este ejemplo, se sobreimpone un <canvas>
sobre el vídeo. (Advertencia: este vídeo contiene imágenes potencialmente impresionantes en que un apuesto empleado de Opera y sus hijos son amenazados por un puntero de ratón gigante.)
Nótese que el <canvas>
no cubre totalmente el vídeo. Hemos hecho el canvas 40 píxeles más corto que la altura de vídeo, para que el área del vídeo donde aparecen los controles no quede cubierta. Esto asegura que, si el usuario desplaza el ratón sobre la parte inferior del vídeo, haya una parte suficiente del elemento <video>
asomando por detrás del canvas para recibir el evento hover y hacer que se muestren los controles. El acceso por teclado a los controles debería funcionar independientemente de los elementos que lo cubren, pero actualmente el soporte de teclado varía entre navegadores.
Tus propios controles
<video>
y <audio>
(que cubriremos en un futuro artículo) son ejemplos de los nuevos elementos para medios del DOM de HTML5, que expone una potente API que proporciona a los desarrolladores control sobre la reproducción de películas a través de toda una serie de nuevos métodos y propiedades de JavaScript. Vamos a echar un vistazo a algunos de los más relevantes para construir nosotros mismos un sencillo controlador personalizado:
play()
ypause()
- Obviamente, estos métodos inician y detienen la reproducción de vídeo.
play()
siempre lanza el vídeo desde la posición actual de reproducción. Cuando una película se carga por primera vez, esta posición será el primer fotograma de la película. Hay que tener en cuenta que no hay métodostop()
: si quieres detener la reproducción y "rebobinar" al inicio de la película, tendrás que hacerpause()
y cambiar tú mismo mediante programación la posición de reproducción actual. volume
- Este atributo se puede utilizar para leer o establecer el volumen de la pista de audio del vídeo, tomando un valor en coma flotante que va desde 0.0 (silencio) a 1.0 (el más alto).
muted
- Independientemente de
volumen
, un vídeo puede silenciarse. currentTime
- Al leerse, este atributo devuelve la posición actual de reproducción en segundos, de nuevo expresada en coma flotante. Dar valor a este atributo mueve (si es posible) la posición de reproducción al índice de tiempo especificado. (Nótese que ni fijar
currentTime
ni moverse están implementados actualmente en Opera.)
Además, los elementos de medios también disparan una serie de eventos como parte de su modelo de procesamiento, eventos a los que podemos escuchar y a los que nos podemos enganchar. Como ejemplo, sólo nos fijaremos en algunos de ellos:
loadeddata
- El navegador ha cargado suficientes datos como para iniciar la reproducción de vídeo en la posición actual.
play
ypause
- Se ha iniciado o interrumpido la reproducción. Si estamos controlando el vídeo desde JavaScript, queremos escuchar estos eventos para garantizar que las llamadas a los métodos
play()
ypause()
retornan con éxito. timeupdate
- La posición de reproducción actual ha cambiado porque se está reproduciendo la película, un script la ha modificado mediante programación, o el usuario ha decidido saltar a un punto diferente del vídeo.
ended
- Hemos llegado al final de la película, y el elemento
<video>
no está dispuesto en bucle o reproducción inversa (no se trata en este artículo).
Ya tenemos todos los elementos básicos necesarios para crear un controlador sencillo. Antes de empezar, sin embargo, una palabra de advertencia: si estamos construyendo nuestro propio reproductor basado en JavaScript, es evidente que querremos suprimir todos los controles nativos del navegador. Sin embargo, es posible que desees proporcionar esos controles como alternativa, para el caso en que el usuario ha desactivado JavaScript en el navegador. Por esta razón, mantendremos el atributo control
en el marcado y lo eliminaremos en tiempo de ejecución con el script. Alternativamente, también podríamos establecer el valor del atributo como false: ambos enfoques son válidos. Como nuestro reproductor personalizado depende de los scripts para funcionar, generaremos el propio marcado del reproductor usando JavaScript.
Véase el ejemplo de controles de vídeo HTML mediante scripts en acción. El script es muy descriptivo y ganaría con un poco de limpieza antes de ser utilizado en un entorno de producción, pero espero que ayude a ilustrar algunas de las nuevas y poderosas posibilidades que abre el vídeo HTML5. Con un poco de conocimiento de JavaScript, ahora es fácil para los desarrolladores web crear reproductores personalizados de vídeo que complementen a la perfección sus diseños, sin la necesidad de crear reproductores de vídeo Flash a medida.