Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Another: Force Chrome to fully buffer mp4 video

Tags:

I've seen a few threads about this, but with no answers, so I thought I'd add another to the grave yard of polluted youtube related pages.

I've got a 100MB mp4 video that needs to be fully downloaded by the browser,

However theres no event that fires when its been fully downloaded, and Chrome seems to stop buffering any more of the video until the current video time has almost reached the end of the buffer, then it requests more.

How can I get the browsers to fully download the video and buffer it 100%?

Thanks

like image 695
owenmelbz Avatar asked Aug 15 '13 11:08

owenmelbz


People also ask

Can you force YouTube to buffer full video?

Force buffering of the entire video For this you can use SmartVideo for YouTube Chrome Extension. Once intalling the extension, you get an additional option at the bottom of the video, click Global Preferences, and tick the box for Smart Buffer, as shown in the image below.

How do I download a buffered video in Chrome?

Just go to the browser settings and then enable the cache. If it is already enabled you can increase the cache limit to something appreciable if you watch big videos so that whole of it resides in the cache itself and then you can save even large buffered videos to your disk and watch them later.


2 Answers

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> 
like image 120
Offbeatmammal Avatar answered Sep 25 '22 05:09

Offbeatmammal


My solution is for a much smaller video than the OP described, however the desired behaviour is the same: Prevent the video from beginning playback until the video is fully buffered. Video should play for returning users if the video is already cached.

Below answer was heavily influenced by this answer and has been tested on Chrome, Safari and Firefox.

Javascript file:

    $(document).ready(function(){       // The video_length_round variable is video specific.       // In this example the video is 10.88 seconds long, rounded up to 11.       var video_length_round = 11;        var video = document.getElementById('home_video_element');       var mp4Source = document.getElementById('mp4Source');        // Ensure home_video_element present on page       if(typeof video !== 'undefined'){          // Ensure video element has an mp4Source, if so then update video src         if(typeof mp4Source !== 'undefined'){           $(mp4Source).attr('src', '/assets/homepage_video.mp4');         }          video.load();          // Ensure video is fully buffered before playing         video.addEventListener("canplay", function() {           this.removeEventListener("canplay", arguments.callee, false);            if(Math.round(video.buffered.end(0)) >= video_length_round){             // Video is already loaded             this.play();            } else {             // Monitor video buffer progress before playing             video.addEventListener("progress", function() {               if(Math.round(video.buffered.end(0)) == video_length_round){                 this.removeEventListener("progress", arguments.callee, false);                 video.play();               }             }, false);           }         }, false);       }     }); 

Above javascript updates the source of a video element such as this one:

    <video id="home_video_element" loop="" poster="/assets/home/video_poster_name.jpg" preload="auto">       <source id="mp4Source" type="video/mp4">     </video> 
like image 35
AlexanderRD Avatar answered Sep 24 '22 05:09

AlexanderRD