ExoPlayer は、インターネット経由でメディアをストリーミングするためによく使用されます。基盤となるネットワーク リクエストを行うために、複数のネットワーク スタックをサポートしています。ネットワーク スタックの選択は、ストリーミングのパフォーマンスに大きな影響を与える可能性があります。
このページでは、選択したネットワーク スタックを使用するように ExoPlayer を構成する方法の概要、使用可能なオプションのリスト、アプリのネットワーク スタックを選択する方法に関するガイダンス、ストリーミング メディアのキャッシュを有効にする方法について説明します。
特定のネットワーク スタックを使用するように ExoPlayer を構成する
ExoPlayer は DataSource
コンポーネントを介してデータを読み込みます。このコンポーネントは、アプリコードから挿入された DataSource.Factory
インスタンスから取得されます。
アプリで再生する必要があるのが HTTP(S) コンテンツのみの場合は、ネットワーク スタックを選択する方法は簡単です。アプリが挿入する DataSource.Factory
インスタンスを、使用するネットワーク スタックに対応する HttpDataSource.Factory
のインスタンスに更新するだけです。アプリが
ローカル ファイルなど、HTTP(S) 以外のコンテンツを再生するには、
DefaultDataSource.Factory
:
Kotlin
DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))
Java
new DefaultDataSource.Factory( ... /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));
この例の PreferredHttpDataSource.Factory
は、対応するファクトリ、
優先ネットワークスタックですDefaultDataSource.Factory
レイヤは、Google Cloud
HTTP(S) 以外のソース(ローカル ファイルなど)に対してリクエストできます。
次の例は、Cronet ネットワーク スタックを使用し、http(s) 以外のコンテンツの再生もサポートする ExoPlayer
を作成する方法を示しています。
Kotlin
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. val cronetDataSourceFactory = CronetDataSource.Factory(cronetEngine, executor) // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). val dataSourceFactory = DefaultDataSource.Factory(context, /* baseDataSourceFactory= */ cronetDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory) ) .build()
Java
// Given a CronetEngine and Executor, build a CronetDataSource.Factory. CronetDataSource.Factory cronetDataSourceFactory = new CronetDataSource.Factory(cronetEngine, executor); // Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds // in support for requesting data from other sources (such as files, resources, // etc). DefaultDataSource.Factory dataSourceFactory = new DefaultDataSource.Factory( context, /* baseDataSourceFactory= */ cronetDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)) .build();
サポートされているネットワーク スタック
ExoPlayer は、HttpEngine、Cronet、OkHttp、および Android の ネットワークスタックを使用できるようになります。ExoPlayer を拡張して、Google Cloud の 他のネットワーク スタックに実装することもできます。
HTTP エンジン
HttpEngine Android で推奨されるデフォルト ネットワーク スタックの API 34(S 拡張機能 7)ほとんどの場合、内部で Cronet ネットワーク スタックを使用しますが、 QUIC プロトコルを介して HTTP、HTTP/2、HTTP/3 をサポート
ExoPlayer は、HttpEngineDataSource.Factory
で HttpEngine をサポートしています。このデータソース ファクトリーは、特定のネットワーク スタックを使用するように ExoPlayer を構成するで説明されているように挿入できます。
Cronet
Cronet は、Android アプリがライブラリとして利用できる Chromium ネットワーク スタックです。Cronet は、ExoPlayer によって作成されたものを含む、アプリの動作に必要なネットワーク リクエストのレイテンシを抑え、スループットを向上させる複数のテクノロジーを利用します。QUIC プロトコル経由の HTTP、HTTP/2、HTTP/3 をネイティブにサポートしています。Cronet は、YouTube をはじめとする世界最大のストリーミング アプリで使用されています。
ExoPlayer は、Cronet ライブラリを介して Cronet をサポートしています。使用方法の詳細については、ライブラリの README.md
をご覧ください。Cronet ライブラリは、次の 3 つの基盤となる Cronet 実装を使用できます。
- Google Play 開発者サービス: ほとんどの場合、この実装を使用し、Google Play 開発者サービスが使用できない場合は Android の組み込みネットワーク スタック(
DefaultHttpDataSource
)にフォールバックすることをおすすめします。 - Cronet Embedded: ユーザーの割合が高い場合に適しています。 Google Play 開発者サービスが十分に提供されていない市場にある場合、または 使用する Cronet 実装の正確なバージョンを制御する必要がある場合。「 Cronet Embedded の主なデメリットは、 説明します。
- Cronet のフォールバック: Cronet の実装のフォールバック実装
Android の組み込みネットワーク スタックのラッパーとしての Cronet の API。本来は
ExoPlayer では使用しない(Android の組み込みネットワーク スタックを使用するため)
直接(
DefaultHttpDataSource
を使用)する方が効率的です。
OkHttp
OkHttp は、最新のネットワーク スタックです。 は、多くの一般的な Android アプリで広く使用されています。サポートされているのは HTTP と HTTP/2 ですが、QUIC を介した HTTP/3 はまだサポートされていません。
ExoPlayer は、OkHttp ライブラリを介して OkHttp をサポートしています。使用方法の詳細については、ライブラリの README.md
をご覧ください。
できます。OkHttp ライブラリを使用する場合、ネットワーク スタックはアプリ内に埋め込まれます。これは Cronet Embedded に似ていますが、OkHttp は大幅に小さく、アプリに追加されるサイズは 1 MB 未満です。
Android の組み込みネットワーク スタック
ExoPlayer は、Android の組み込みネットワーク スタックの使用をサポートしています。
DefaultHttpDataSource
と DefaultHttpDataSource.Factory
:
ExoPlayer のコアライブラリです。
正確なネットワーク スタックの実装は、基盤となるデバイスで実行されているソフトウェアによって異なります。ほとんどのデバイスでは HTTP のみがサポートされています(つまり、 HTTP/2 と HTTP/3 over QUIC はサポートされていません)。
その他のネットワーク スタック
アプリは、他のネットワーク スタックを ExoPlayer と統合することもできます。
これを行うには、ネットワーク スタックをラップする HttpDataSource
と、対応する HttpDataSource.Factory
を実装します。ExoPlayer の Cronet ライブラリと OkHttp ライブラリは、この方法の良い例です。
純粋な Java ネットワーク スタックと統合する場合は、DataSourceContractTest
を実装して、HttpDataSource
実装が正しく動作することを確認することをおすすめします。OkHttp ライブラリの OkHttpDataSourceContractTest
は、この方法の良い例です。
ネットワーク スタックの選択
次の表に、ExoPlayer でサポートされているネットワーク スタックの長所と短所を示します。
ネットワーク スタック | プロトコル | APK サイズへの影響 | 注 |
---|---|---|---|
HTTP エンジン | HTTP HTTP/2 QUIC を介した HTTP/3 |
なし | API 34 または S Extensions 7 でのみ使用可能 |
Cronet(Google Play 開発者サービス) | HTTP HTTP/2 QUIC 経由の HTTP/3 |
小 (100 KB 未満) |
Google Play 開発者サービスが必要です。Cronet のバージョンが自動更新されました |
Cronet(埋め込み) | HTTP HTTP/2 QUIC 経由の HTTP/3 |
大 (~ 8 MB) |
アプリ デベロッパーによって管理されている Cronet のバージョン |
Cronet(代替) | HTTP (デバイスによって異なる) |
小 (100 KB 未満) |
ExoPlayer には非推奨 |
OkHttp | HTTP HTTP/2 |
小 (1 MB 未満) |
|
組み込みネットワーク スタック | HTTP (デバイスによって異なる) |
なし | 実装はデバイスによって異なります |
QUIC プロトコルを介した HTTP/2 と HTTP/3 は、メディアを大幅に改善できます。 パフォーマンスが向上します特に、サイズの大きいアダプティブ メディアをストリーミングする場合は、 コンテンツ配信ネットワーク(CDN)を使用して配信する場合、 どちらのプロトコルを使用することで CDN の運用効率が 大幅に向上します このため、コンテンツがホストされているサーバーがこれらのプロトコルをサポートしている場合、HttpEngine と Cronet が QUIC を介した HTTP/2 と HTTP/3 の両方をサポートしていること(および OkHttp が HTTP/2 をサポートしていること)は、Android の組み込みネットワーク スタックを使用する場合と比較して大きなメリットとなります。
メディア ストリーミングのみを検討する場合は、Google Play 開発者サービスが利用できない場合は DefaultHttpDataSource
にフォールバックする Google Play 開発者サービスが提供する HttpEngine または Cronet を使用することをおすすめします。この推奨事項は、ほとんどのデバイスで QUIC を介した HTTP/2 と HTTP/3 の使用を有効にし、APK サイズの大幅な増加を回避するバランスの取れたものです。この推奨事項には例外があります。アプリを実行するデバイスの大部分で Google Play 開発者サービスが使用できない可能性が高い場合は、Cronet Embedded または OkHttp を使用することをおすすめします。組み込みネットワーク スタックの使用は、APK サイズが重要な懸念事項である場合や、メディア ストリーミングがアプリの機能のごく一部である場合に許容されます。
通常、メディアだけでなく、アプリが行うすべてのネットワーキングに単一のネットワーク スタックを選択することをおすすめします。これにより、リソース(ソケットなど)を効率的にプールし、ExoPlayer と他のアプリ コンポーネント間で共有できます。
アプリではメディアの再生に関連しないネットワーク処理を行う必要があるため、ネットワーク スタックを選択する際には、メディア ストリーミングのみに関する上記の推奨事項、ネットワーク処理を行う他のコンポーネントの要件、アプリに対するそれらの相対的な重要性を考慮する必要があります。
メディアのキャッシュ保存
ExoPlayer は、読み込まれたバイトをディスクにキャッシュに保存し、ネットワークから同じバイトを繰り返し読み込まないようにします。これは、現在の日付を 同じ項目の繰り返し再生を行えるようになります
キャッシュには、専用のキャッシュ ディレクトリと CacheDataSource.Factory
を指す SimpleCache
インスタンスが必要です。
Kotlin
// Note: This should be a singleton in your app. val databaseProvider = StandaloneDatabaseProvider(context) // An on-the-fly cache should evict media when reaching a maximum disk space limit. val cache = SimpleCache( downloadDirectory, LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider) // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. val cacheDataSourceFactory = CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory) // Inject the DefaultDataSource.Factory when creating the player. val player = ExoPlayer.Builder(context) .setMediaSourceFactory( DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build()
Java
// Note: This should be a singleton in your app. DatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context); // An on-the-fly cache should evict media when reaching a maximum disk space limit. Cache cache = new SimpleCache( downloadDirectory, new LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider); // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. DataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory() .setCache(cache) .setUpstreamDataSourceFactory(httpDataSourceFactory); // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory)) .build();