[html] Wait until an HTML5 video loads

I have a video tag, that I dynamically change its source as I am letting the user to choose from a number of videos from the database. The problem is that when I change the src attribute the video doesn't load even if I tell it to.

Here is my code:

$("#video").attr('src', 'my_video_'+value+'.ogg');
$("#video").load();
while($("#video").readyState !== 4) {
        console.log("Video is not ready");
};

The code still stays in a infinite loop.

Any help?

EDIT:

To Ian Devlin:

//add an listener on loaded metadata
v.addEventListener('loadeddata', function() {
    console.log("Loaded the video's data!");
    console.log("Video Source: "+ $('#video').attr('src'));
    console.log("Video Duration: "+ $('#video').duration);
}, false);

Ok this is the code I have now. The source prints great, but I still can't get the duration :/

This question is related to html html5-video

The answer is


You don't really need jQuery for this as there is a Media API that provides you with all you need.

var video = document.getElementById('myVideo');
video.src = 'my_video_' + value + '.ogg';
video.load();

The Media API also contains a load() method which: "Causes the element to reset and start selecting and loading a new media resource from scratch."

(Ogg isn't the best format to use, as it's only supported by a limited number of browsers. I'd suggest using WebM and MP4 to cover all major browsers - you can use the canPlayType() function to decide on which one to play).

You can then wait for either the loadedmetadata or loadeddata (depending on what you want) events to fire:

video.addEventListener('loadeddata', function() {
   // Video is loaded and can be played
}, false);

call function on load:

<video onload="doWhatYouNeedTo()" src="demo.mp4" id="video">

get video duration

var video = document.getElementById("video");
var duration = video.duration;

you can use preload="none" in the attribute of video tag so the video will be displayed only when user clicks on play button.

_x000D_
_x000D_
<video preload="none">
_x000D_
_x000D_
_x000D_


In response to the final part of your question, which is still unanswered... When you write $('#video').duration, you're asking for the duration property of the jQuery collection object, which doesn't exist. The native DOM video element does have the duration. You can get that in a few ways.

Here's one:

// get the native element directly
document.getElementById('video').duration

Here's another:

// get it out of the jQuery object
$('#video').get(0).duration

And another:

// use the event object
v.bind('loadeddata', function(e) {
  console.log(e.target.duration);
});