Cover by Jeff Fulton, Steve Fulton

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

O'Reilly logo

Preloading Video in JavaScript

It is often necessary to preload a video before you do anything with it. This is especially true when using video with HTML5 Canvas because many times what you want to do goes beyond the simple act of playing the video.

We are going to leverage the DOM and JavaScript to create a preload architecture that can be reused and expanded upon. We are still not using Canvas, but this process will lead directly to it.

To do this, we must first embed the video in the HTML page in the same way we have done previously in this chapter. However, this time, we are going to add <div> with the id of loadingStatus.

Note

In practice, you probably would not display the loading status on the HTML page.

This <div> will report the percentage of the video that has loaded when we retrieve it through JavaScript:

<div>
<video loop controls id="thevideo" width="320" height="240" preload="auto">
 <source src="muirbeach.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' >
 <source src="muirbeach.webm"type='video/webm; codecs="vp8, vorbis"' >
 <source src="muirbeach.ogg" type='video/ogg; codecs="theora, vorbis"'>
</video>

<div>

<div id="loadingStatus">
0%
</div>

In JavaScript, we need to create the same type of eventWindowLoaded() function that we have created many times previously in this book. This function is called when the HTML page has finished loading. In eventWindowLoaded() we need to create two listeners for two more events that are dispatched from the HTMLVideoElement object:

progress

Dispatched when the video object has updated information about the loading progress of a video. We will use this event to update the percentage text in the loadingStatus <div>.

canplaythrough

Dispatched when the video has loaded enough that it can play in its entirety. This event will let us know when to start playing the video.

Below is the code that creates the listeners for those events:

function eventWindowLoaded() {
   var videoElement = document.getElementById("thevideo");

   videoElement.addEventListener('progress',updateLoadingStatus,false);
   videoElement.addEventListener('canplaythrough',playVideo,false);

}

The updateLoadingStatus() function is called when the progress event is dispatched from the video element. This function calculates the percent loaded by calculating the ratio of the already-loaded bytes (videoElement.buffered.end(0)) by the total bytes (videoElement.duration), and dividing that value by 100. That value is then displayed by setting the innerHTML property of the loadingStatus <div>, as shown in Figure 6-5. Remember, this is only for displaying the progress. We still need to do something once the video has loaded.

Note

At the time of this writing, Firefox did not support the videobuffered property, but this was planned for Firefox version 4.0.

function updateLoadingStatus() {

   var loadingStatus = document.getElementById("loadingStatus");
   var videoElement = document.getElementById("thevideo");
   var percentLoaded = parseInt(((videoElement.buffered.end(0) /
      videoElement.duration) * 100));
    document.getElementById("loadingStatus").innerHTML =   percentLoaded + '%';

}
Preloading a video in JavaScript

Figure 6-5. Preloading a video in JavaScript

The playVideo() function is called when the video object dispatches a canplaythrough event. playVideo() calls the play() function of the video object, and the video starts to play:

function playVideo() {
   var videoElement = document.getElementById("thevideo");
   videoElement.play();

}

Example 6-5 gives the full code for preloading video.

Example 6-5. Basic HTML5 preloading video

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH6EX5: Basic HTML5 Preloading Video</title>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
   var videoElement = document.getElementById("thevideo");

   videoElement.addEventListener('progress',updateLoadingStatus,false);
   videoElement.addEventListener('canplaythrough',playVideo,false);

}

function updateLoadingStatus() {

   var loadingStatus = document.getElementById("loadingStatus");
   var videoElement = document.getElementById("thevideo");
   var percentLoaded = parseInt(((videoElement.buffered.end(0) /
      videoElement.duration) * 100));
    document.getElementById("loadingStatus").innerHTML =   percentLoaded + '%';

}

function playVideo() {
   var videoElement = document.getElementById("thevideo");
   videoElement.play();

}
</script>

</head>
<body>
<div>
<video loop controls id="thevideo" width="320" height="240" preload="auto">
 <source src="muirbeach.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' >
 <source src="muirbeach.webm"type='video/webm; codecs="vp8, vorbis"' >
 <source src="muirbeach.ogg" type='video/ogg; codecs="theora, vorbis"'>

</video>

<div>

<div id="loadingStatus">
0%
</div>

</div>
</body>
</html>

A Problem with Events and Embedded Video in HTML5

Now that we have gone through this exercise, we have to give you some bad news. While the code we presented for CH6EX5.html works in most HTML5-compliant web browsers, the code stopped working in Google Chrome as we finished up the first draft of this book. This was upsetting because we used Chrome as our primary platform when developing and testing all the book’s examples.

With a bit of investigation, we discovered that Chrome was not firing the canplaythrough or progress events. At the same time, Firefox removed the load event. While these were anecdotal occurrences, they lead to one common truth: the HTML5 specification is not finished. This is an obvious but important fact to note. If you are developing for HTML5 or Canvas, you are developing with a moving target.

Specifically in CH6EX5.html, we found that the process of embedding the <video> tag in the HTML page was the reason why the events weren’t firing in Chrome. In order to make this example work in Chrome, you need to add a call to playVideo() in the eventWindowLoaded() function, like this:

function eventWindowLoaded() {
   var videoElement = document.getElementById("thevideo");

   videoElement.addEventListener('progress',updateLoadingStatus,false);
   videoElement.addEventListener('canplaythrough',playVideo,false);
   playVideo()
}

However, this code will not solve the core problem: we need a reliable way to know when a video has finished loading so we can use it on the canvas. In Example 6-6, we will show you a way to make that happen.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required