changing source on html5 video tag

sashn picture sashn · Mar 8, 2011 · Viewed 314.5k times · Source

i'm trying to build a video player, that works everywhere. so far i'd be going with:

<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>

(as seen on several sites, for example video for everybody) so far, so good.

but now i also want some kind of playlist/menu along with the video player, from which i can select other videos. those should be opened within my player right away. so i will have to "dynamically change the source of the video" (as seen on dev.opera.com/articles/everything-you-need-to-know-html5-video-audio/ - section "Let's look at another movie") with javascript. let's forget about the flashplayer (and thus IE) part for the time being, i will try to deal with that later.

so my JS to change the <source> tags should be something like:

<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>

problem is, this doesnt work in all browsers. namely, firefox =O there is a nice page, where you can observe the problem i'm having: http://www.w3.org/2010/05/video/mediaevents.html

as soon as i trigger the load() method (in firefox, mind you), the video player dies.

now i have found out that when i don't use multiple <source> tags, but instead just one src attribute within the <video> tag, the whole thing DOES work in firefox.

so my plan is to just use that src attribute and determine the appropriate file using the canPlayType() function.

am i doing it wrong somehow or complicating things??

Answer

mattdlockyer picture mattdlockyer · Aug 27, 2013

I hated all these answers because they were too short or relied on other frameworks.

Here is "one" vanilla JS way of doing this, working in Chrome, please test in other browsers:

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);