Solution
I created a working example of the accepted answer which uses an XHR and reports loading progress through a bar.
It's available here.
https://github.com/synthecypher/full-preload
Question
I've noticed when I create a <video>
element with sources and call load()
it will load to about 36% and then stops unless you play()
it, at which time it'll continue to load the rest of the video as it plays.
However, I want to ensure the entire video loaded before hand as it's an element in a timed exercise and if the internet connection drops during the exercise I will have to detect such an event and restart the exercise.
I assume this is a built in feature of the HTML5 media elements but is it possible to override this native functionality?
I've attempted to load the entire video source as a arraybuffer
using an XMLHttpRequest
which is then converted to a blob and set as the src
of a <source>
element in my <video>
element.
This does work however, it isn't ideal as I can't report the progress of download to the user through the use of progress bar as an XHR is a syncronous operation and will cause my JavaScript to hang until a response is received. I know XHR2 now has this funtionality but I have to support IE8+ so that's not an option.
Is there an easier more elegant solution to my problem, which will report progress?
Requirements
<video>
element's <source>
before playing.If you have the source, you can pre-download the data to a blob in JavaScript and play when ready.
The following should work if the video is on your server. If not, you'll run into CORS issues.
var video = document.getElementById("Your video element id")
var url = "Some video url"
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onload = function(oEvent) {
var blob = new Blob([oEvent.target.response], {type: "video/yourvideosmimmetype"});
video.src = URL.createObjectURL(blob);
//video.play() if you want it to play on load
};
xhr.onprogress = function(oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded/oEvent.total;
// do something with this
}
}
xhr.send();