web-dev-qa-db-ja.com

別の:強制的にChrome mp4ビデオを完全にバッファリングする

私はこれについていくつかのスレッドを見ましたが、答えはありませんでしたので、私は汚染されたYouTube関連ページの墓場に別のものを追加すると思いました。

ブラウザーで完全にダウンロードする必要がある100MBのmp4ビデオがあります。

ただし、完全にダウンロードされたときに発生するイベントはなく、Chromeは、現在のビデオ時間がバッファの最後にほぼ達するまで、ビデオのバッファリングを停止するようです。 。

ブラウザでビデオを完全にダウンロードし、100%バッファリングするにはどうすればよいですか?

ありがとう

21
Owen

悲しいことにChrome-他のHTML5ブラウザと同様に、ダウンロード対象を賢くしようとし、不必要な帯域幅の使用を回避しようとします...これに非常に苦しんでいるため、より多くの事前バッファリングを強制する拡張機能があります!)

とはいえ、良いサーバーと良好な接続でこれが頻繁に必要になることはありませんでした-しかし、何かが必要な場合、私が見つけた唯一の解決策は少しのハンマーです... Ajaxを使用してファイルをダウンロードします再生して、それをビデオ要素のソースにロードします。

以下のサンプルでは、​​ブラウザがm4v/mp4をサポートしていることを前提としています。Chromeを保証できない場合(canPlayTypeテストを使用して、ユーザーに最適なビデオ形式を選択することをお勧めします)。また、必要なサイズのビデオをどれだけうまく処理できるかをテストする必要があります(かなり大きいものを試しましたが、これが確実に処理できる上限はわかりません)

サンプルも非常にシンプルです...リクエストを開始し、読み込み中にユーザーに何も伝えません-サイズビデオでは、おそらく興味を引くためにプログレスバーを表示したいと思うでしょう。 。

このプロセスのもう1つの欠点は、ファイルを完全にダウンロードするまで再生を開始しないことです。バッファからビデオを動的に表示したい場合は、出血しているEdge(現時点では) http://francisshanahan.com/index.php/2013/build-an-mpeg-dash-player-のような投稿で説明されているMediaSourceの世界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

私の解決策は、説明されているOPよりもはるかに小さいビデオ用ですが、望ましい動作は同じです:ビデオが完全にバッファリングされるまでビデオの再生を開始しません。ビデオが既にキャッシュされている場合、リピートユーザーのためにビデオを再生する必要があります。

以下の回答はこれに大きく影響されました answer そして、Chrome、Safari、Firefoxでテストされています。

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

上記のJavaScriptは、次のような動画要素のソースを更新します。

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