ExoPlayer のバッファリング戦略
ExoPlayer Version Investigated: 2.9.6
LoadControl インターフェイスを実装するクラスは、ExoPlayer のバッファリング戦略を定義します。 バッファリング戦略は、次のような質問に答えます:
- do we need to load more media data?
- do we have enough media data to start playback?
バッファリング戦略はバッファの管理、メディアデータのダウンロード(これは MediaSource)、メディアデータの再生(これは Renderer)に責任を持ちません。 バッファリングストラテジーは、再生されるメディアフォーマットには不可知論的であり、「相談役」的な役割しか持ちません。 ExoPlayer が新しいメディア データをロードすべきかどうかを LoadControl に「尋ね」、その答えを無視することがあります(たとえば、ExoPlayer がすでにメディア データをダウンロードしている場合など)。 これは、LoadControl インターフェイスのカスタマイズ可能な実装です。
DefaultLoadControl を使用して、たとえば、以下の設定を行うことができます。 ExoPlayer が完全なセグメントをバッファリングしなかった場合でも、少なくとも bufferForPlaybackMs のメディア データがあればすぐに再生を開始します。
DefaultLoadControl は、これらの各設定に対してデフォルト値を持ちます。 v2.9.6では、これらの値は次のとおりです。
bufferForPlaybackMs |
|
minBufferMs |
|
maxBufferMs |
|
bufferForPlaybackAfterRebufferMs |
しかし、だ。 の値は、ExoPlayerのバージョンによって異なります。 例えば、ExoPlayer v2.7.3 と v2.8.0 の間で、ビデオ ストリームの maxBufferMs は 30 秒から 50 秒に変更されました。
ExoPlayer のモジュール式アーキテクチャでは、独自のバッファリング戦略 (LoadControl インターフェイスを実装する) を実装して ExoPlayer に接続することも可能です。 しかし、それは別の投稿のためのトピックです。
起動時間の短縮
ExoPlayer では、再生が開始される前にどれだけのメディア データが必要かを簡単に設定することができます。 このブログ シリーズの最初のパートでは、QoE メトリクスとしての起動時間の重要性を強調しました。 アカマイが2016年に発表したレポートによると、「起動が再生開始まで2秒以上かかると視聴者はビデオを放棄し始め、1秒遅れるごとに、視聴者のおよそ6%がさらに離れる。10秒遅れると、視聴者のほぼ半数が離れている」
ExoPlayer バージョン 2.9.6 ではデフォルトで、再生開始前に 2.5 秒のメディア データのバッファリングを要求しています。 バッファリングされるデータを少なくすることで、起動時間を短縮することが可能です。 一方では、メディア データ バッファリング値を下げると、ビデオの起動時間が短くなりますが、欠点は、起動時のリバッファリング メトリクスの増加にもつながる可能性があることです。 以下のチャートは、再生を開始する前に必要なメディア データの最小量を引き下げた場合の影響を示しています。
bufferForPlaybackMs のデフォルト値である 2.5 秒は保守的な値なので、これを下げることは良い選択だと思います。
以下のグラフは、この構成オプションの値を変更した場合の 3 Mbps ストリームの開始時間への影響を示します (サーバーへのラウンド トリップ時間とサーバーが他の場所からコンテンツを取得する必要があるかは考慮に入れません)。 たとえば、3 Mbps のストリームを再生する 4 Mbps 接続では、メディア データを 1.5 秒間バッファリングしてから再生を開始するように ExoPlayer を設定すると、メディア データを 2.5 秒間バッファリングするデフォルト設定での 1.9 秒ではなく、理論上の起動時間が 1.1 秒になります。
次のセクションでは、起動時間およびハンド ウェーブ遅延を低減する ExoPlayer を構成する方法について説明します。 ExoPlayer に慣れていない場合は、まず Google の Codelabs on Media streaming with ExoPlayer.
Configuring the DefaultLoadControl
ExoPlayer インスタンスを、次のコード(または同様のコード)を使用してデフォルト LoadControl の実装で作成したと仮定します:
ExoPlayer player = ExoPlayerFactory.ExoPlayerFactory.DefaultLoadControl ContrastLoadControl = ExoPlayerFactory.DefaultLoadControl ExoPlayer の構成。newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
new DefaultLoadControl())
DefaultLoadControl.Builder を使用して、デフォルト LoadControl を構成することができます:
/* DefaultLoadControl.Builder をインスタンス化してください。 */
DefaultLoadControl.Builder builder = new DefaultLoadControl.Builder();
/* 再生が開始または再開する前にバッファされるメディア データのミリ秒数です。 */
final long loadControlStartBufferMs = 1500;
ユーザー アクション イベント後に再生が開始または再開される前に、何ミリ秒のメディア データをバッファする必要があるかを設定するために、新しい DefaultLoadControl を構成します。setBufferDurationMs(
DefaultLoadControl.DEFAULT MAX BUFFER MS,
loadControlStartBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* 実際の DefaultLoadControl インスタンスを構築 */
DefaultLoadControl loadControl = builder.DefaultControl.DefaultBufferMs(DefaultLoadControlStartBufferMS);
DefaultControl.DefaultControl.DefaultDurationMs(DefaultLoadControl.DefaultBuffer_For_RayBack_AFTER_REBUFFER_MS)createDefaultLoadControl();
/* 設定した DefaultLoadControl で ExoPlayer をインスタンス化 */
ExoPlayer player = ExoPlayerFactory.ExoPlayerFactory.ExoPlayerFactory.ExoPlayerFactory.ExoPlayerFactory;
DefaultLoadControl をインスタンス化する。newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(), loadControl);
Lowering Rebuffering Metrics for VOD Content
起動時間の短縮につながる設定を構成するほかに、バッファするメディア データ量として DefaultLoadControl を構成でき、VOD コンテンツのバッファリング指標に影響を与えることが可能です。
ExoPlayer v2.9.6 は、デフォルトで、可能であれば 50 秒間のメディア データを内部バッファにロードします (maxBufferMs の設定)。 VOD コンテンツの場合、この値を増やすと、ネットワーク帯域幅の変動に対応するための余裕ができ、再バッファリング メトリクスの低下をもたらしますが、欠点は ExoPlayer のメモリ使用量も増加することです。 メモリ使用量を低く抑えることは、ローエンドのデバイスでは重要です。 もう 1 つの欠点は、再生が早期に停止した場合に帯域幅が無駄になることです。
VOD コンテンツのセットアップに最適な値を見つけるには、構成オプションのさまざまな値で A/B テストを行って、再バッファリング速度とメモリ使用量の間で良い取引ができるものを見つけることが推奨されます。 控えめに、この値を例えば次のように増やすことをお勧めします。 8807>
DefaultLoadControl の設定
デフォルトの LoadControl 実装で ExoPlayer インスタンスを作成するとします (前のセクション「起動時間の短縮 – DefaultLoadControl を設定する」で示したとおりです)。
/* DefaultLoadControl.Builder を使用して、DefaultLoadControl を設定することができます。 */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/* バッファするメディア データの最大量 (ミリ秒単位):*/
/* DefaultLoadControl.Builder のインスタンスを作成します。 */
final long loadControlMaxBufferMs = 60000;
/* DefaultLoadControlを設定し、何
ミリ秒のメディアデータをバッファリングするかという設定を使用するよう設定します。 */
builder.setBufferDurationsMs(
DefaultLoadcontrol.DEFAULT MIN BUFFER MS,
loadControlMaxBufferMs,
/* 起動時間を短縮するには、以下の行も変更します */
DefaultLoadControl.DefaultBufferMs(DefaultLoadControl.BufferMS,
BufferMS,
BufferDurationsMs)DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
/* 実際の DefaultLoadControl インスタンスを構築 */
DefaultLoadControl loadControl = builder.createDefaultLoadControl();
/* 設定した DefaultLoadControl で ExoPlayer をインスタンス化 */
ExoPlayer player = ExoPlayerFactory.ExoPlayerFactory.ExoPlayerFactory.ExoPlayerFactory.ExoPlayerFactory;
DefaultLoadControl をインスタンス化する。newSimpleInstance(
new DefaultRenderersFactory(this),
new DefaultTrackSelector(),
loadControl);
minBufferMs と maxBufferMs が異なる値の場合、バッファの補充はバースト的挙動となります。 ExoPlayer は、メディア データの maxBufferMs でバッファがいっぱいになるまでバッファリングし、その後 minBufferMs に減少するまで待機します (主に VOD に適用されます)。 バッファレベルがメディアデータのminBufferMsを下回ると、ExoPlayerはメディアデータのmaxBufferMs相当のバッファを持つまで、再びメディアデータのロードを開始します。 このようなバースト的な動作は、リバッファリングの問題につながる可能性があります。 ExoPlayer v2.9.6 以前のバージョンでは、これらの値が異なるため、この動作がデフォルトとなっています。 v2.9.6 では、minBufferMs のデフォルト値は 15000 で、maxBufferMs は 50000 です。
さらにリバッファリングの機会を減らすために、minBufferMs を maxBufferMs と同じ値に設定し、ExoPlayer で常に大きなバッファを維持することをお勧めします。 ExoPlayerチームは実験を行い、minBufferMsをmaxBufferMsと同じ値に設定すること(そしてバッファリング動作をバースト型からドリップ型に変更すること)で、リバッファリングイベントを大幅に減らし、バッテリー使用量をわずかに増やすだけであることを発見しました。 実際、v2.10 以降、ExoPlayer は、ビデオのユースケースについて、デフォルトの minBufferMs を maxBufferMs と同じにして 50 秒に設定します。
DefaultLoadControl.Builder を使用して DefaultLoadControl を構成する方法:
/* DefaultLoadControl.Builder をインスタンス化してください。 */
DefaultLoadControl.Builder builder = new
DefaultLoadControl.Builder();
/* 何ミリ秒のメディア データを常にバッファに入れるか。 */
final long loadControlBufferMs = DefaultloadControl.MAX_BUFFER_MS; /* ExoPlayer 2.9.6 では50000ミリ秒です */
/* DefaultLoadControlを設定して、同じ値を */
builder に使用するように設定する。setBufferDurationMs(
loadControlBufferMs,
loadControlBufferMs,
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS,
DefaultLoadControl.DefaultBufferMs).DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS);
概要
LoadControl は ExoPlayer のバッファリング戦略へのエントリ ポイントとなるものです。 ExoPlayer には、ほとんどのユースケースで十分な LoadControl インターフェイスのデフォルトの、まだ設定可能な実装が付属しています。
これまでの議論に基づいて、以下は推奨事項の簡単な要約です。 これは、潜在的にリバッファリング イベントの数を増加させるという欠点があります。
この投稿を書くにあたり、同僚の Christian Worm Mortensen と Laust Brock-Nannestad からフィードバックをいただいたことに感謝いたします。
次のブログ投稿では、ExoPlayer のビットレート選択戦略について説明します。 ご期待ください!
8807