javascript - reproducir - cambio de fuente en la etiqueta de video html5
reproductor de video html5 gratis (14)
De acuerdo con la especificación
La modificación dinámica de un elemento fuente y su atributo cuando el elemento ya está insertado en un elemento de video o audio no tendrá ningún efecto. Para cambiar lo que se está reproduciendo, simplemente use el atributo src en el elemento multimedia directamente, posiblemente haciendo uso del método canPlayType () para elegir entre los recursos disponibles. En general, la manipulación manual de elementos fuente después de que el documento ha sido analizado es un enfoque innecesariamente complicado.
Entonces, aparentemente, lo que intentas hacer no se supone que funcione.
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, muy bien.
pero ahora también quiero algún tipo de lista de reproducción / menú junto con el reproductor de video, desde el cual puedo seleccionar otros videos. esos deberían abrirse dentro de mi reproductor de inmediato. entonces 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/ - section "Veamos otra película ") con javascript. Olvidémonos de la parte de flashplayer (y por lo tanto de IE) por el momento, intentaré lidiar con eso más adelante.
entonces mi JS para cambiar las etiquetas <source>
debería ser algo así como:
<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. a saber, firefox = O hay una buena página, donde puedes observar el problema que estoy teniendo: http://www.w3.org/2010/05/video/mediaevents.html
tan pronto como active el método load () (en firefox, fíjate), el reproductor de video muere.
ahora descubrí que cuando no uso múltiples etiquetas <source>
, sino solo un atributo src dentro de la etiqueta <video>
, todo funciona en Firefox.
entonces mi plan es simplemente usar ese atributo src y determinar el archivo apropiado usando la función canPlayType() .
¿Lo estoy haciendo mal de alguna manera o complicando las cosas?
En lugar de obtener el mismo reproductor de video para cargar archivos nuevos, ¿por qué no borrar todo el elemento <video>
y volver a crearlo? La mayoría de los navegadores lo cargarán automáticamente si los src son correctos.
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);
Esta es mi solución:
<video id="playVideo" width="680" height="400" controls="controls">
<source id="sourceVideo" src="{{video.videoHigh}}" type="video/mp4">
</video>
<br />
<button class="btn btn-warning" id="{{video.videoHigh}}" onclick="changeSource(this)">HD</button>
<button class="btn btn-warning" id="{{video.videoLow}}" onclick="changeSource(this)">Regular</button>
<script type="text/javascript">
var getVideo = document.getElementById("playVideo");
var getSource = document.getElementById("sourceVideo");
function changeSource(vid) {
var geturl = vid.id;
getSource .setAttribute("src", geturl);
getVideo .load()
getVideo .play();
getVideo .volume = 0.5;
}
</script>
He estado investigando esto por bastante tiempo y estoy tratando de hacer lo mismo, así que espero que esto ayude a otra persona. He estado usando crossbrowsertesting.com y lo estoy probando literalmente en casi todos los navegadores conocidos por el hombre. La solución que tengo actualmente funciona en Opera, Chrome, Firefox 3.5+, IE8 +, iPhone 3GS, iPhone 4, iPhone 4s, iPhone 5, iPhone 5s, iPad 1+, Android 2.3+, Windows Phone 8.
Cambiando dinámicamente las fuentes
Cambiar dinámicamente el video es muy difícil, y si quieres una alternativa de Flash, tendrás que quitar el video de la página DOM / y volver a agregarlo para que Flash se actualice porque Flash no reconocerá las actualizaciones dinámicas en Flash vars. Si va a usar JavaScript para cambiarlo dinámicamente, eliminaría completamente todos los elementos <source>
y simplemente usar canPlayType
para establecer el src
en JavaScript y break
o return
después del primer tipo de video compatible y no olvide actualizar dinámicamente el flash var mp4. Además, algunos navegadores no registrarán que usted cambió la fuente a menos que llame a video.load()
. Creo que el problema con .load()
que estaba experimentando se puede solucionar llamando primero a video.pause()
. La eliminación y adición de elementos de video puede ralentizar el navegador porque continúa almacenando en búfer el video eliminado, pero hay una solución alternativa .
Soporte de navegador cruzado
En cuanto a la parte real del navegador, también llegué a Video For Everybody . Ya probé el plugin MediaelementJS Wordpress, que resultó causar muchos más problemas de los que resolvió. Sospecho que los problemas se debieron al complemento de Wordpress y no a la biblioteca en realidad. Estoy intentando encontrar algo que funcione sin JavaScript, si es posible. Hasta ahora, lo que se me ocurrió es este HTML sencillo:
<video width="300" height="150" controls="controls" poster="http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg" class="responsive">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg" />
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4" />
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm" type="video/webm" />
<source src="http://alex-watson.net/wp-content/uploads/2014/07/big_buck_bunny.iphone.mp4" type="video/mp4" />
<source src="http://alex-watson.net/wp-content/uploads/2014/07/big_buck_bunny.iphone3g.mp4" type="video/mp4" />
<object type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" width="561" height="297">
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
<param name="allowFullScreen" value="true" />
<param name="wmode" value="transparent" />
<param name="flashVars" value="config={''playlist'':[''http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg'',{''url'':''http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'',''autoPlay'':false}]}" />
<img alt="No Video" src="http://sandbox.thewikies.com/vfe-generator/images/big-buck-bunny_poster.jpg" width="561" height="297" title="No video playback capabilities, please download the video below" />
</object>
<strong>Download video:</strong> <a href="video.mp4">MP4 format</a> | <a href="video.ogv">Ogg format</a> | <a href="video.webm">WebM format</a>
</video>
Notas importantes :
- Terminó poniendo el ogg como el primer
<source>
porque Mac OS Firefox deja de intentar reproducir el video si encuentra un MP4 como el primer<source>
. - Los tipos MIME correctos son importantes. Los archivos .ogv deben ser
video/ogg
, novideo/ogv
- Si tienes video HD, el mejor transcodificador que he encontrado para archivos OGG de calidad HD es Firefogg
- El archivo
.iphone.mp4
es para iPhone 4+ que solo reproducirá videos que sean MPEG-4 con video H.264 Baseline 3 y audio AAC. El mejor transcodificador que encontré para ese formato es Handbrake, usar el preajuste de iPhone y iPod Touch funcionará en iPhone 4+, pero para hacer funcionar el iPhone 3GS necesitas usar el preajuste de iPod que tiene una resolución mucho más baja que agregué comovideo.iphone3g.mp4
. - En el futuro, podremos usar un atributo de
media
en los elementos<source>
para orientar los dispositivos móviles con consultas de medios, pero ahora los dispositivos anteriores de Apple y Android no lo soportan lo suficientemente bien.
Editar :
- Todavía utilizo Video for Everybody, pero ahora he pasado a usar FlowPlayer para controlar Flash Fallback, que tiene una impresionante API de JavaScript que se puede usar para controlarla.
Intenta mover la fuente OGG a la parte superior. Me he dado cuenta de que a veces Firefox se confunde y detiene al jugador cuando el que quiere jugar, OGG, no es el primero.
Vale la pena intentarlo.
Lo resolví con este método simple
function changeSource(url) {
var video = document.getElementById(''video'');
video.src = url;
video.play();
}
Odiaba todas estas respuestas porque eran demasiado cortas o dependían de otros marcos.
Aquí está la "única" forma JS vainilla de hacer esto, trabajando en Chrome, por favor prueba en otros navegadores:
http://jsfiddle.net/mattdlockyer/5eCEu/2/
HTML:
<video id="video" width="320" height="240"></video>
JS:
var video = document.getElementById(''video'');
var source = document.createElement(''source'');
source.setAttribute(''src'', ''http://www.tools4movies.com/trailers/1012/Kill%20Bill%20Vol.3.mp4'');
video.appendChild(source);
video.play();
setTimeout(function() {
video.pause();
source.setAttribute(''src'', ''http://www.tools4movies.com/trailers/1012/Despicable%20Me%202.mp4'');
video.load();
video.play();
}, 3000);
Solo ponga un div y actualice el contenido ...
<script>
function setvideo(src) {
document.getElementById(''div_video'').innerHTML = ''<video autoplay controls id="video_ctrl" style="height: 100px; width: 100px;"><source src="''+src+''" type="video/mp4"></video>'';
document.getElementById(''video_ctrl'').play();
}
</script>
<button onClick="setvideo(''video1.mp4'');">Video1</button>
<div id="div_video"> </div>
Tengo una aplicación web similar y no estoy enfrentando ese tipo de problema en absoluto. Lo que hago es algo como esto:
var sources = new Array();
sources[0] = /path/to/file.mp4
sources[1] = /path/to/another/file.ogg
etc.....
luego, cuando quiero cambiar las fuentes, tengo una función que hace algo como esto:
this.loadTrack = function(track){
var mediaSource = document.getElementsByTagName(''source'')[0];
mediaSource.src = sources[track];
var player = document.getElementByTagName(''video'')[0];
player.load();
}
Hago esto para que el usuario pueda abrirse paso a través de una lista de reproducción, pero puede buscar UserAgent y luego cargar el archivo apropiado de esa manera. Traté de usar múltiples etiquetas de origen, como todo el mundo sugirió en Internet, pero me pareció mucho más limpio y mucho más confiable para manipular el atributo src de una sola etiqueta de origen. El código anterior fue escrito desde la memoria, por lo que puede haber pasado por alto algunos de los detalles, pero la idea general es cambiar dinámicamente el atributo src de la etiqueta fuente utilizando javascript, cuando corresponda.
Tu plan original me parece bien. Probablemente encontrará más peculiaridades del navegador que tratan con la gestión dinámica de los elementos <source>
, como se indica aquí en la nota de la especificación W3:
La modificación dinámica de un elemento fuente y su atributo cuando el elemento ya está insertado en un elemento de video o audio no tendrá ningún efecto. Para cambiar lo que se está reproduciendo, simplemente use el atributo src en el elemento multimedia directamente, posiblemente haciendo uso del método canPlayType () para elegir entre los recursos disponibles. En general, la manipulación manual de los elementos fuente después de que el documento ha sido analizado es un enfoque innecesariamente [sic] complicado.
http://dev.w3.org/html5/spec/Overview.html#the-source-element
Usar las etiquetas <source />
me resultó difícil en Chrome 14.0.835.202 específicamente, aunque funcionó bien para mí en FireFox. (Esto podría ser mi falta de conocimiento, pero pensé que una solución alternativa podría ser útil de todos modos). Así que terminé simplemente usando una etiqueta <video />
y estableciendo el atributo src directamente en la etiqueta del video. La función canPlayVideo(''<mime type>'')
se usó para determinar si el navegador específico podría reproducir o no el video de entrada. Lo siguiente funciona en Firefox y Chrome.
Incidentalmente, tanto FireFox como Chrome están jugando en el formato "ogg", aunque Chrome recomienda "webm". Primero puse el cheque para el soporte de navegador de "ogg" porque otras publicaciones han mencionado que FireFox prefiere primero la fuente ogg (es decir, <source src="..." type="video/ogg"/>
). Pero, no he probado (y dudo mucho) si el orden en el código hace alguna diferencia al configurar el "src" en la etiqueta de video.
HTML
<body onload="setupVideo();">
<video id="media" controls="true" preload="auto" src="">
</video>
</body>
JavaScript
function setupVideo() {
// You will probably get your video name differently
var videoName = "http://video-js.zencoder.com/oceans-clip.mp4";
// Get all of the uri''s we support
var indexOfExtension = videoName.lastIndexOf(".");
//window.alert("found index of extension " + indexOfExtension);
var extension = videoName.substr(indexOfExtension, videoName.length - indexOfExtension);
//window.alert("extension is " + extension);
var ogguri = encodeURI(videoName.replace(extension, ".ogv"));
var webmuri = encodeURI(videoName.replace(extension, ".webm"));
var mp4uri = encodeURI(videoName.replace(extension, ".mp4"));
//window.alert(" URI is " + webmuri);
// Get the video element
var v = document.getElementById("media");
window.alert(" media is " + v);
// Test for support
if (v.canPlayType("video/ogg")) {
v.setAttribute("src", ogguri);
//window.alert("can play ogg");
}
else if (v.canPlayType("video/webm")) {
v.setAttribute("src", webmuri);
//window.alert("can play webm");
}
else if (v.canPlayType("video/mp4")) {
v.setAttribute("src", mp4uri);
//window.alert("can play mp4");
}
else {
window.alert("Can''t play anything");
}
v.load();
v.play();
}
Vengo con esto para cambiar la fuente de video de forma dinámica. El evento "canplay" en algún momento no se activa en Firefox, así que he agregado "loadedmetadata". También hago una pausa en el video anterior si hay uno ...
var loadVideo = function(movieUrl) {
console.log(''loadVideo()'');
$videoLoading.show();
var isReady = function (event) {
console.log(''video.isReady(event)'', event.type);
video.removeEventListener(''canplay'', isReady);
video.removeEventListener(''loadedmetadata'', isReady);
$videoLoading.hide();
video.currentTime = 0;
video.play();
},
whenPaused = function() {
console.log(''video.whenPaused()'');
video.removeEventListener(''pause'', whenPaused);
video.addEventListener(''canplay'', isReady, false);
video.addEventListener(''loadedmetadata'', isReady, false); // Sometimes Firefox don''t trigger "canplay" event...
video.src = movieUrl; // Change actual source
};
if (video.src && !video.paused) {
video.addEventListener(''pause'', whenPaused, false);
video.pause();
}
else whenPaused();
};
Yaur: aunque lo que ha copiado y pegado es un buen consejo, esto no significa que sea imposible cambiar elegantemente el elemento de origen de un elemento de video HTML5, incluso en IE9 (o IE8 para el caso). (Esta solución NO implica reemplazando todo el elemento de video, ya que es una mala práctica de codificación).
Una solución completa para cambiar / cambiar videos en etiquetas de video HTML5 a través de JavaScript se puede encontrar here y se prueba en todos los navegadores HTML5 (Firefox, Chrome, Safari, IE9, etc.).
Si esto ayuda, o si tiene problemas, hágamelo saber.
Modernizr funcionó como un encanto para mí.
Lo que hice es que no utilicé <source>
. De alguna manera esto jodió las cosas, ya que el video solo funcionó la primera vez que se llamó load (). En cambio, utilicé el atributo de fuente dentro de la etiqueta de video -> <video src="blabla.webm" />
y usé Modernizr para determinar qué formato era compatible con 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 desea usar Modernizr , siempre puede usar CanPlayType() .