Wait until an HTML5 video loads
Asked Answered
S

4

59

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

Strudel answered 13/12, 2012 at 17:2 Comment(2)
$("#video").load(); What are you doing here? The .load() method is used to load content via Ajax and inject it into the element.Puffy
possible duplicate of HTML5 Video - File Loading Complete Event?Sean
F
95

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);
Fawnia answered 14/12, 2012 at 8:42 Comment(7)
I know, which is why I said to use MP4 AND WebM - WebM works on Firefox and Opera.Fawnia
Thanks, your answer seems to have helped me but not exactly. I have edited the questionStrudel
Ok, what gets printed out as the duration? Also you don't need the $('video') stuff, you can simply use: this.src for the source and this.duration for the duration, as this = v and v is a handle to the video. I think this is what's wrong as the jQuery $('#video') doesn't know what .duration is.Fawnia
@IanDevlin what if I needed to dynamically add a video element to the page using JavaScript, when I drop a file onto the web page? At that point, I am using HTML drag and drop capability. I am able to do this with an image with the help of the FileReader API, once the reader finishes loading the file that was dropped.Leastways
The better way around these conflicting variables could be $('#myVideo')[0].load() because while the jQuery wrapper has a .load() function you can always access the underlying DOM elements directly with [index] syntax.Bromidic
how to do it in typescriptPlatt
@manishkumar here's a Typescript HTML5 audio wrapper gist.github.com/devfred/b34aafcb4402ac318ecaaa91f6816fc7 - That can easily be converted to wrap an HTML5 video API.Brookins
I
14

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);
});
Iquique answered 2/10, 2013 at 5:6 Comment(1)
For your second method, as Anthony mentioned above, you can also use this syntax: $('#video')[0].durationTori
Z
2

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

<video preload="none">
Zacatecas answered 26/4, 2018 at 8:20 Comment(0)
F
0

call function on load:

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

get video duration

var video = document.getElementById("video");
var duration = video.duration;
Ferris answered 3/7, 2017 at 8:14 Comment(1)
This event isn't fired on video tags in latest Chrome (ubuntu, not sure if specific)Rossini

© 2022 - 2024 — McMap. All rights reserved.