ネットワーク スタック

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 を使用する ExoPlayer の作成方法を示しています。 サポートしており、HTTP(S) 以外のコンテンツの再生もサポートしています。

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 をサポートしています。Google Chat では ExoPlayer を構成して、このデータソース ファクトリを 特定のネットワークスタックに トラフィックを分散させるためです

Cronet

Cronet は、 Android アプリでライブラリとして利用できるようにした Chromium ネットワーク スタック。Cronet は 複数のテクノロジーの利点を活かしながら レイテンシを短縮し リクエストを含む、アプリが機能するために必要なネットワーク リクエストのスループット。 ExoPlayer が作成しますHTTP、HTTP/2、HTTP/3 over QUIC をネイティブにサポート 通信できます。Cronet は世界最大規模のストリーミングアプリで 使用されています 。

ExoPlayer は、 Cronet ライブラリ。 使用方法の詳細については、ライブラリの README.md をご覧ください。 できます。なお、Cronet ライブラリでは、基盤となる Cronet を 3 つ使用して 実装:

  1. Google Play 開発者サービス: この実装は、ほとんどのケースでの使用が推奨されます。 Android の組み込みのネットワークスタックに フォールバックすることで (DefaultHttpDataSource)。Google Play 開発者サービスが使用できない場合。
  2. Cronet Embedded: ユーザーの割合が高い場合に適しています。 Google Play 開発者サービスが十分に提供されていない市場にある場合、または 使用する Cronet 実装の正確なバージョンを制御する必要がある場合。「 Cronet Embedded の主なデメリットは、 説明します。
  3. 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 の組み込みネットワーク スタックの使用をサポートしています。 DefaultHttpDataSourceDefaultHttpDataSource.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 では HTTP/2 と HTTP/3 の両方をサポートしています。 QUIC 経由(および HTTP/2 に対する OkHttp のサポート)は、 独自のネットワーク スタックによって実現され、 コンテンツもこれらのプロトコルをサポートしています。

メディア ストリーミングを単独で検討する場合は、HttpEngine または Google Play 開発者サービス提供の Cronet を DefaultHttpDataSource にフォールバック Google Play 開発者サービスが使用できない場合。この最適化案は ほとんどのデバイスで QUIC を介した HTTP/2 と HTTP/3 の使用を有効にすることのバランスを取る。 APK サイズの大幅な増加を防ぐこれには例外があります。 おすすめします。Google Play 開発者サービスを利用できない可能性があるケース かなりの割合のデバイスでアプリが動作するので Cronet Embedded または OkHttp を使用することをおすすめします。組み込みの APK のサイズを重視する場合や、メディアがメディアの場合、ネットワーク スタックが許容される場合があります。 ストリーミングはアプリの機能のほんの一部にすぎません。

メディアだけでなく、通常は単一のネットワーク スタックを アプリによって実行されるすべてのネットワーキングの ログを提供します。これにより、リソースに対して (ソケットなど)を効率的にプールし、ExoPlayer と 説明します。

アプリで必要になる可能性が高いため、ネットワークとは無関係なネットワーキングを実行する必要があるから 選択されるネットワーク スタックについては、最終的に 個別のメディア ストリーミングに関する前述の推奨事項、 その他のコンポーネントの概要と、それらのコンポーネントに対する 。

メディアのキャッシュ保存

ExoPlayer は、読み込みの繰り返しを防ぐために、読み込まれたバイトをディスクにキャッシュ保存することをサポートしています。 同じバイトをネットワークから受信します。これは、現在の日付を 同じ項目の繰り返し再生を行えるようになります

キャッシュ保存には、専用キャッシュを指す SimpleCache インスタンスが必要です 2 つのディレクトリと CacheDataSource.Factory で構成できます。

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