Tiffany B. Brown

a mish-mosh of stuff

The HTML5 video progress event

UPDATE: Thanks to zcorpan’s comments, I have posted a follow-up entry that should clarify the current status of the video element and its properties.
I have been playing around with the HTML5 video interface lately, trying to understand what can be done with it, and how each browser supports its features as set forth in the specification (which is a working draft, and far from a final version).

Consider this in the first in a series of note-style posts that I will write (or perhaps not) about the HTML5 video interface as I develop an HTML5 video player interface.

The progress event is fired as the browser loads more of the media file. It may not be fired reliably, however. Chrome, for example, will not fire the progress event if it has cached the video file.

Only Firefox provides a means to calculate the amount of the video that has been loaded. The progress event object includes total and loaded properties that reflect the total size of the video file, and the amount the browser has retrieved from the server. This is also a reflection of how each browser handles video downloads.

Firefox requests partial content on the initial page load, then pauses downloading until the play event is fired. After the play event is fired — whether when the user clicks the ‘play’ button or the video tag has the autoplay attribute — Firefox resumes downloading the video file.

Safari, Chrome, and Opera conversely, download the entire video on page load — they automatically buffer by default. Opera and Chrome, however, will make the video available for play almost immediately, while Safari takes several seconds to download a larger portion of the file. Firefox will behave similarly if when the autobuffer attribute is present.

Presumably because they auto-buffer video, neither Safari, Chrome, nor Opera offer a means by which to detect either the video’s size, nor how much of the video has loaded.

Some example code for handling the progress event (assuming we’re wrapping this video element in a <div> tag with an id of ‘container’). This will return the percentage of the video loaded in Firefox (and other browsers that don’t auto-buffer), and fail silently in other browsers.

var container = document.getElementById('container');
var video = document.createElement(video);
// only Firefox and Opera support Ogg ... oh yeah Chrome does too.
video.setAttribute('src','movie.ogv');
function progressHandler(e){
      if(e.total && e.loaded){
           // percentage of video loaded
          var proportion = Math.round( e.loaded / e.total );
          return proportion * 100;
      } else {
           // do nothing because we're autobuffering.
      }
}
video.addEventListener('progress',progressHandler,false);
container.appendChild(video);
  • zcorpan

    Chrome also supports Ogg.

    The .loaded and .total attributes were removed from the spec because they don't make sense for media, since media is downloaded in parts if the user seeks to a time that has not been downloaded yet, and past data is thrown away from the cache when the browser sees fit. I would expect these to be removed from Firefox at some point. The replacement (which Safari and Chrome support, IIRC) is video.buffered which returns a TimeRanges object and gives accurate information about what is downloaded/still in cache.

  • tiffanybbrown

    Thanks for telling me about Chrome. I forgot it supported both Ogg and H.264.

    Thanks also for the backstory and details of the change to buffered. The buffered is a property of the video element, though, not of the progress event. I will clarify that in the post and update the code.

  • Jeanine Meyer

    I have two problems concerning video that may relate to buffering and/or different browsers.
    The following works nicely when I run it locally using Chrome, http://faculty.purchase.edu/jeanine.meyer/html5workshop/videobounce1.html
    or when I run it locally or remotely using Firefox.
    When I run it from the server, an ugly black rectangle shows up in the upper corner, probably where the video is prior to re-positioning.

    The following http://faculty.purchase.edu/jeanine.meyer/html5workshop/videobounce3.html
    works on in Firefox.

    Any suggestions most appreciated.

    Jeanine
    jeanine.meyer@purchase.edu

  • tiffany

    It looks like the problem has to do with the video format. You’re using an .ogv file, which works fine in Chrome, Opera, and Firefox. But it won’t work in Safari because Safari only supports H.264 / MPEG-4 videos. Try using Miro Video Converter (http://www.mirovideoconverter.com/) to re-encode your video.

  • Unnivm

    Hi Tiffany, I tried your piece of code, but it is not displaying how much video loaded.e.total returns undefined.

  • Anonymous

    Now that I think about it, it may have to do with timing. Try listening for the onMetaData or similar loading event.

  • Anonymous

    They syntax should be e.loaded. You’re looking for how much is loaded within the event object. Which browser are you using? This will only work in browsers in which there is not an auto buffer.

  • Unnivm

    I think I had tried in FireFox 4+.