web-dev-qa-db-ja.com

YoutubeのHTML5ビデオプレーヤーはどのようにバッファリングを制御しますか?

私はYouTubeビデオを見ていて、そのビデオプレーヤーの一部を調査することにしました。私が見たほとんどのHTML5ビデオとは異なり、YouTubeのビデオプレーヤーは通常のビデオソースを実行せず、代わりにソースとしてblobのURLを利用していることに気付きました。

以前、私はHTML5ビデオをテストしましたが、サーバーが最初からビデオ全体のストリーミングを開始し、残りのビデオ全体をバックグラウンドでバッファリングすることがわかりました。つまり、ビデオが300 MBの場合、300 MBがすべてダウンロードされます。途中までシークすると、シーク位置から最後までダウンロードを開始します。

Youtubeはこの方法では機能しません(少なくともChromeでは)。代わりに、バッファリングを制御して、一時停止している間は一定量だけバッファリングします。また、関連する部分のみをバッファリングするように見えるため、スキップする場合は、監視される可能性が低い部分をバッファリングしないようにします。

これがどのように機能するかを調査しようとしたときに、ビデオのsrcタグに_blob:http%3A//www.youtube.com/ee625eee-2802-49b2-a13f-eb374d551d54_の値があり、 blobs を示し、 typed array 。これら2つのリソースを使用して、mp4ビデオをblobにロードし、HTML5ビデオタグに表示できます。

しかし、私が今行き詰まっているのは、YouTubeが作品をどのように扱うかです。ネットワークトラフィックを見ると、リクエストは_http://r6---sn-p5q7ynee.c.youtube.com/videoplayback_に送信され、バイナリビデオデータが1.1 MBのチャンクで返されます。また、HTML5ビデオリクエストによるほとんどの通常のリクエストは、ストリーミング中に206レスポンスコードを受信するように見えますが、YouTubeのplayvideoコールは200を返します。

残念ながら失敗した(Range httpヘッダーの設定を介して)バイト範囲のみをロードしようとしました(ビデオに付属するビデオのメタデータがなかったためと思います)。

この時点で、YouTubeがこれをどのように達成するかを理解するのに行き詰まっています。私はいくつかのアイデアを思いつきましたが、どれも完全に販売されていません。

1)Youtubeは、_/videoplayback_の呼び出しごとに、自己完結型のビデオとオーディオのチャンクを送信しています。これはアップロード側の負担がかなり大きいようで、これらをつなぎ合わせて1つの見た目のないビデオのように見せることは難しいようです。また、$('video').duration$('video').currentTimeの呼び出しから判断すると、ビデオタグは1つの完全なビデオであると考えているようです。最後に、vidoe srcタグは変更されないため、単一のblobで動作していて、blobを切り替えていないと思います。

2)Youtubeは、ビデオ配列全体にプリサイズされた空のblobを作成し、ダウンロード時に断片でblobを更新します。次に、ユーザーが最後にダウンロードされた部分に近づきすぎていないことを確認します(ユーザーがblobのダウンロードされていないセクションに入らないようにします)。これで私が見る問題は、javascriptを介してblobを動的に更新する方法が見当たらないことです(多分私はそれについてグーグルで問題を抱えているだけです)

3)Youtubeはメタデータをダウンロードし、ダウンロード時にビデオを追加することで、ブロブの構築を開始します。この方法で発生する問題は、ポストバッファリングされた領域でシークを処理する方法が理解できないことです。

多分私はちょうど私の目の前にある明白な答えが欠けているだけです。誰かが何かアイデアを持っていますか?


49
KallDrexx

GoogleChromeのAppDataを見ると、YouTube動画を再生しているときに、セグメント化されたファイルにバッファリングされていることがわかります。 YouTubeにアップロードされた動画はセグメント化されているため、タイムフレームが現在のセグメントの外にある場合、バーの最初のクリックでタイムフレームを完全に特定することはできません。

セグメントの数は、ビデオの長さと、ビデオの再生を開始および停止する時間によって異なります。

ビデオのタイムフレームにリンクされている場合、そのタイムフレームの前に来るセグメントのバッファリングはスキップされます。

残念ながら、ビデオ再生のコーディングについてはあまり知りませんが、これが正しい方向を示していることを願っています。

5
MilanSxD

ページにcanvas要素があります。たぶんこれが役立ちます http://html5doctor.com/video-canvas-magic/

私たちはビデオがセグメント化されていることを知っていました。問題は、それらをどのようにつなぎ合わせるかです。私は、実際のビデオ要素は再生作業を行わないと考え、データソースをサポートし、キャンバス要素に各フレームの継ぎ目を描画します。

var v = document.getElementById('v'); 
var canvas = document.getElementById('c');
v.addEventListener('play', function(){ 
   if(v.paused || v.ended) return false; 
   c.drawImage(v,0,0,w,h); 
   setTimeout(draw,20,v,c,w,h); 
},false);

4
vetch

わかりましたので、知っておくべきことは、YouTubeがこの素晴らしいオープンソースに基づいているということです Project 。ブラウザごとに動作が異なり、ブラウザがWEBMのようなより強力なデコードをサポートしている場合は、それを使用してGoogleの帯域幅を節約します。また、これを見ると デモ 次に、ビデオ全体を「オフラインストレージ」と呼ばれるものにダウンロードするセクションがあります。私はchromeがそれを持っていることを知っています、そしてすべての場合ではないいくつかのブラウザはブロブの代わりにビデオソース全体を使用する必要があります。そのためブロブはビデオとのユーザーインタラクションに応じてストリーミングしています。はい、動画は1つのファイルであり、動画の時間とチャンクを分割できるポイントを示す小さなデータベースのような、その動画のメタデータがあります。

詳細については、プロジェクトのドキュメントをご覧ください。デモをご覧になることをお勧めします。

3
Adminy

YoutubeはMedia Source Extensionsをサポートするブラウザーでのみこの機能を使用しているため、この機能のためにブラウザーが残りのすべてを決定します。

3
Albi Patozi