Another: Force Chrome to fully buffer mp4 video

Sadly Chrome – like other HTML5 browsers – tries to be smart about what it’s downloading and avoids unnecessary bandwidth usage… this means that sometimes we’re left with a sub-optimal experience (ironically YouTube suffers from this so much that there are extensions to force more pre-buffering!)

That said, I’ve not found this to be required too often with a good server and a good connection – but if you need something the only solution I have found is a bit of a sledgehammer… use Ajax to download the file that you want to play and then load that into the source for the video element.

The sample below assumes your browser supports m4v/mp4 – you’ll probably want to use the canPlayType test to select the most appropriate video format for your users if you can’t guarantee (eg) Chrome. You’ll also want to test to see how well it handles videos of the size you want (I’ve tried some fairly large ones but not sure what upper limit this will reliably handle)

The sample is also pretty simple… it kicks off the request and doesn’t communicate anything to the user while it’s loading – with your size video you’re probably going to want to show a progress bar just to keep them interested…

the other downside of this process is that it’s not going to start playing until you’ve fully downloaded the file – if you want to go deeper into displaying the video dynamically from your buffer then you’ll need to start delving into the bleeding edge (at the moment) world of MediaSource as described in posts like http://francisshanahan.com/index.php/2013/build-an-mpeg-dash-player-from-scratch/

<!DOCTYPE html>
<html>
<head>
<title>Preload video via AJAX</title>
</head>
<body>
<script>
console.log("Downloading video...hellip;Please wait...")
var xhr = new XMLHttpRequest();
xhr.open('GET', 'BigBuck.m4v', true);
xhr.responseType="blob";
xhr.onload = function(e) {
  if (this.status == 200) {
    console.log("got it");
    var myBlob = this.response;
    var vid = (window.webkitURL || window.URL).createObjectURL(myBlob);
    // myBlob is now the blob that the object URL pointed to.
    var video = document.getElementById("video");
    console.log("Loading video into element");
    video.src = vid;
    // not needed if autoplay is set for the video element
    // video.play()
   }
  }

xhr.send();
</script>

<video id="video" controls autoplay></video>

</body>
</html>

Leave a Comment