2013-08-15 18 views
19

Widziałem kilka wątków na ten temat, ale bez odpowiedzi, więc pomyślałem, że dodam kolejną do grobu z zanieczyszczonymi stronami związanymi z youtube.Kolejna: zmuś Chrome do pełnego buforowania wideo mp4

Mam 100MB wideo MP4, który musi być w pełni pobrany przez przeglądarkę,

Jednak tam nie zdarzenie, które pożary podczas jego zostały w pełni pobrane i Chrome wydaje się zatrzymać buforowanie więcej o filmie aż bieżący czas wideo prawie osiągnął koniec bufora, a następnie żąda więcej.

Jak mogę przekonać przeglądarki, aby w pełni pobierały wideo i buforowały je w 100%?

Dzięki

Odpowiedz

37

Niestety Chrome - podobnie jak innych przeglądarek HTML5 - stara się być mądry o tym, co to pobieranie i pozwala uniknąć niepotrzebnego zużycia pasma ... oznacza to, że czasami jesteśmy w lewo z doświadczeniem nieoptymalne (ironicznie YouTube cierpi z tego powodu, że istnieją rozszerzenia, które wymuszają więcej wstępnego buforowania!)

To powiedziawszy, nie uważam, aby wymagało to zbyt często z dobrym serwerem i dobrym połączeniem - ale jeśli potrzebujesz czegoś Jedyne rozwiązanie, które znalazłem to trochę młot ... użyj Ajax, aby pobrać plik, który chcesz odtworzyć, a następnie załaduj go do źródła dla elementu wideo.

Poniższy przykład zakłada, że ​​przeglądarka obsługuje m4v/mp4 - prawdopodobnie będziesz chciał użyć testu canPlayType, aby wybrać najbardziej odpowiedni format wideo dla użytkowników, jeśli nie możesz zagwarantować (np.) Chrome. Będziesz także chciał przetestować, aby zobaczyć, jak dobrze radzi sobie z filmami o takiej wielkości, jaką chcesz (wypróbowałem dość duże, ale nie jestem pewny, który górny limit to będzie niezawodnie obsługiwać)

Próbka jest również bardzo prosta. .. wywołuje żądanie i nie komunikuje niczego użytkownikowi podczas jego ładowania - przy rozmiarze wideo prawdopodobnie chcesz pokazać pasek postępu tylko po to, aby ich zainteresować ...

z drugiej strony wadą tego procesu jest to, że nie zacznie się grać, dopóki nie pobierzesz pełnego pliku - jeśli chcesz głębiej wyświetlać wideo dynamicznie z bufora, musisz zacząć zagłębiać się w krwawiącą krawędź (przy moment) świata MediaSource zgodnie z opisem w wpisach takich jak 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> 
2

Proponowane rozwiązanie jest o wiele mniejszy niż wideo PO opisanego, jednakże pożądane zachowanie jest takie same: Zapobieganie wideo od początku odtwarzania wideo aż całkowicie buforowane. Film wideo powinien być odtwarzany dla powracających użytkowników, jeśli wideo jest już zapisane w pamięci podręcznej.

Poniższa odpowiedź była pod dużym wpływem tego answer i została przetestowana w przeglądarce Chrome, Safari i Firefox. Plik

Javascript:

$(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); 
     } 
    }); 

Przede JavaScript aktualizuje źródło elementu wideo, takich jak ten:

<video id="home_video_element" loop="" poster="/assets/home/video_poster_name.jpg" preload="auto"> 
     <source id="mp4Source" type="video/mp4"> 
    </video>