web-dev-qa-db-fra.com

Un autre: Forcer Chrome pour mettre complètement en mémoire tampon la vidéo mp4

J'ai vu quelques discussions à ce sujet, mais sans réponse, j'ai donc pensé en ajouter un autre dans la cour des graves des pages liées à YouTube polluées.

J'ai une vidéo mp4 de 100 Mo qui doit être entièrement téléchargée par le navigateur,

Cependant il n'y a aucun événement qui se déclenche quand il a été complètement téléchargé, et Chrome semble arrêter de mettre plus de mémoire tampon en mémoire jusqu'à ce que le temps vidéo actuel ait presque atteint la fin du tampon, puis il en demande plus .

Comment puis-je faire en sorte que les navigateurs téléchargent entièrement la vidéo et la tamponnent à 100%?

Merci

21
Owen

Malheureusement Chrome - comme les autres navigateurs HTML5 - essaie d'être intelligent sur ce qu'il télécharge et évite l'utilisation inutile de la bande passante ... cela signifie que parfois nous nous retrouvons avec une expérience sous-optimale (ironiquement YouTube souffre tellement de cela qu'il y a des extensions pour forcer plus de pré-tampon!)

Cela dit, je n'ai pas trouvé que cela était trop souvent requis avec un bon serveur et une bonne connexion - mais si vous avez besoin de quelque chose, la seule solution que j'ai trouvée est un peu un marteau ... utilisez Ajax pour télécharger le fichier qui vous souhaitez lire, puis le charger dans la source de l'élément vidéo.

L'exemple ci-dessous suppose que votre navigateur prend en charge m4v/mp4 - vous voudrez probablement utiliser le test canPlayType pour sélectionner le format vidéo le plus approprié pour vos utilisateurs si vous ne pouvez pas garantir (par exemple) Chrome. Vous aurez également besoin de tester pour voir dans quelle mesure il gère les vidéos de la taille que vous voulez (j'en ai essayé quelques-unes assez grandes mais je ne sais pas quelle limite supérieure cela va gérer de manière fiable)

L'échantillon est également assez simple ... il démarre la demande et ne communique rien à l'utilisateur pendant le chargement - avec votre vidéo de taille, vous voudrez probablement afficher une barre de progression juste pour les garder intéressés. .

l'autre inconvénient de ce processus est qu'il ne commencera pas à jouer tant que vous n'aurez pas complètement téléchargé le fichier - si vous souhaitez approfondir l'affichage dynamique de la vidéo à partir de votre tampon, vous devrez commencer à plonger dans le bord saignant ( pour le moment) monde de MediaSource comme décrit dans des articles comme 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>
38
Offbeatmammal

Ma solution est pour une vidéo beaucoup plus petite que l'OP décrit, mais le comportement souhaité est le même: Empêchez la vidéo de commencer la lecture jusqu'à ce que la vidéo soit entièrement tamponnée. La vidéo doit être lue pour les utilisateurs qui reviennent si la vidéo est déjà mise en cache.

La réponse ci-dessous a été fortement influencée par cette réponse et a été testée sur Chrome, Safari et Firefox.

Fichier 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);
      }
    });

Ci-dessus javascript met à jour la source d'un élément vidéo tel que celui-ci:

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