javascript - cambiando la fuente en la etiqueta de video de html5
Estoy tratando de construir un reproductor de video que funcione en todas partes. Hasta ahora, iría con:
<video>
<source src="video.mp4"></source>
<source src="video.ogv"></source>
<object data="flowplayer.swf" type="application/x-shockwave-flash">
<param name="movie" value="flowplayer.swf" />
<param name="flashvars" value='config={"clip":"video.mp4"}' />
</object>
</video>
(como se ve en varios sitios, por ejemplo video para todos) hasta ahora, todo bien.
Pero ahora también quiero algún tipo de lista de reproducción/menú junto con el reproductor de video, desde el cual pueda seleccionar otros videos. Esos deben abrirse dentro de mi reproductor de inmediato. Así que tendré que "cambiar dinámicamente la fuente del video" (como se ve en dev.opera.com/articles/everything-you-need-to-know-html5-video-audio/ - sección "Veamos otra película") con Javascript. Olvidémonos por el momento de la parte del reproductor Flash (y por lo tanto IE), intentaré ocuparme de eso más tarde.
Así que mi JS para cambiar las etiquetas <source> debería ser algo así:
<script>
function loadAnotherVideo() {
var video = document.getElementsByTagName('video')[0];
var sources = video.getElementsByTagName('source');
sources[0].src = 'video2.mp4';
sources[1].src = 'video2.ogv';
video.load();
}
</script>
El problema es que esto no funciona en todos los navegadores. Específicamente, en Firefox hay una página interesante donde puedes observar el problema que estoy teniendo: http://www.w3.org/2010/05/video/mediaevents.html
Tan pronto como ejecuto el método load() (en Firefox, ojo), el reproductor de video deja de funcionar.
Ahora he descubierto que cuando no uso múltiples etiquetas <source>, sino solo un atributo src dentro de la etiqueta <video>, todo sí funciona en Firefox.
Así que mi plan es simplemente usar ese atributo src y determinar el archivo adecuado usando la función canPlayType().
¿Lo estoy haciendo mal de alguna manera o complicando las cosas?
Respuesta #1
Odiaba todas estas respuestas porque eran demasiado cortas o dependían de otros marcos de trabajo.
Aquí hay una manera de hacer esto con JS 'puro', funcionando en Chrome, por favor prueba en otros navegadores:
var video = document.getElementById('video');
var source = document.createElement('source');
source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.mp4');
source.setAttribute('type', 'video/mp4');
video.appendChild(source);
video.play();
console.log({
src: source.getAttribute('src'),
type: source.getAttribute('type'),
});
setTimeout(function() {
video.pause();
source.setAttribute('src', 'http://techslides.com/demos/sample-videos/small.webm');
source.setAttribute('type', 'video/webm');
video.load();
video.play();
console.log({
src: source.getAttribute('src'),
type: source.getAttribute('type'),
});
}, 3000);<video id="video" width="320" height="240"></video>Enlace externo
Respuesta #2
Modernizr funcionó de maravilla para mí.
Lo que hice fue que no usé <source>. De alguna manera, esto estropeó las cosas, ya que el video solo funcionaba la primera vez que se llamaba a load(). En su lugar, usé el atributo source dentro de la etiqueta video -> <video src="blabla.webm" /> y usé Modernizr para determinar qué formato soportaba el navegador.
<script>
var v = new Array();
v[0] = [
"videos/video1.webmvp8.webm",
"videos/video1.theora.ogv",
"videos/video1.mp4video.mp4"
];
v[1] = [
"videos/video2.webmvp8.webm",
"videos/video2.theora.ogv",
"videos/video2.mp4video.mp4"
];
v[2] = [
"videos/video3.webmvp8.webm",
"videos/video3.theora.ogv",
"videos/video3.mp4video.mp4"
];
function changeVid(n){
var video = document.getElementById('video');
if(Modernizr.video && Modernizr.video.webm) {
video.setAttribute("src", v[n][0]);
} else if(Modernizr.video && Modernizr.video.ogg) {
video.setAttribute("src", v[n][1]);
} else if(Modernizr.video && Modernizr.video.h264) {
video.setAttribute("src", v[n][2]);
}
video.load();
}
</script>
Espero que esto te ayude :)
Si no quieres usar Modernizr, siempre puedes usar CanPlayType().
Respuesta #3
Tu plan original me parece bien. Probablemente encontrarás más peculiaridades del navegador al manejar dinámicamente los elementos <source>, como se indica aquí en la nota de la especificación de W3:
Modificar dinámicamente un elemento source y su atributo cuando el elemento ya está insertado en un elemento de video o audio no tendrá efecto. Para cambiar lo que se reproduce, simplemente utiliza el atributo src en el elemento de medios directamente, posiblemente haciendo uso del método canPlayType() para elegir entre los recursos disponibles. En general, manipular manualmente los elementos source después de que el documento ha sido analizado es un enfoque innecesariamente complicado.
http://dev.w3.org/html5/spec/Overview.html#the-source-element
Respuesta #4
Resolví esto con este método simple
function changeSource(url) {
var video = document.getElementById('video');
video.src = url;
video.play();
}
Respuesta #5
En lugar de hacer que el mismo reproductor de video cargue nuevos archivos, ¿por qué no borrar todo el elemento <video> y recrearlo? La mayoría de los navegadores lo cargarán automáticamente si las src son correctas.
Ejemplo (usando Prototype):
var vid = new Element('video', { 'autoplay': 'autoplay', 'controls': 'controls' });
var src = new Element('source', { 'src': 'video.ogg', 'type': 'video/ogg' });
vid.update(src);
src.insert({ before: new Element('source', { 'src': 'video.mp4', 'type': 'video/mp4' }) });
$('container_div').update(vid);
