網路堆疊

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 層則新增了對非 http(s) 來源 (例如本機檔案) 的支援。

以下範例說明如何建構 ExoPlayer,以便使用 Cronet 網路堆疊,並支援播放非 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 也可以擴充,以支援在 Android 上運作的任何其他網路堆疊。

HttpEngine

HttpEngine 是 Android 中從 API 34 (或 S) 建議的預設網路堆疊 擴充功能 7)。在大多數情況下,Cronet 會在內部使用 Cronet 網路堆疊,並支援 HTTP、HTTP/2 和 HTTP/3 透過 QUIC 通訊協定。

ExoPlayer 會透過 HttpEngineDataSource.Factory 支援 HttpEngine。您可以按照「設定 ExoPlayer 以使用特定網路堆疊」一文所述,插入這個資料來源工廠。

鱷魚

Cronet 是 Chromium 網路堆疊是供 Android 應用程式使用的程式庫。Cronet 利用多項技術縮短延遲時間,並提高應用程式運作所需的網路要求總處理量,包括 ExoPlayer 提出的要求。透過 QUIC 原生支援 HTTP、HTTP/2 和 HTTP/3 通訊協定全球部分大型串流應用程式都使用 Cronet,包括 YouTube。

ExoPlayer 會透過其 Cronet 程式庫支援 Cronet。如需詳細的使用說明,請參閱該程式庫的 README.md。請注意,Cronet 程式庫可使用三種基礎 Cronet 實作項目:

  1. Google Play 服務:我們建議在大多數情況下使用這項實作方式,如果 Google Play 服務無法使用,則改用 Android 內建的網路堆疊 (DefaultHttpDataSource)。
  2. 內嵌 Cronet:如果您的使用者中有很大比例位於 Google Play 服務未廣泛提供的市場,或是您想控管使用的 Cronet 實作版本,這可能會是個不錯的選擇。 Cronet Embedded 的主要缺點是將
  3. Cronet 備用方案:Cronet 的備用方案實作會將 Cronet 的 API 做為 Android 內建網路堆疊的包裝函式實作。它應該 不會與 ExoPlayer 搭配使用,因為使用 Android 內建的網路堆疊 直接 (使用 DefaultHttpDataSource) 更有效率。

奧克拉荷馬州

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 但不支援透過 QUIC 的 HTTP/2 和 HTTP/3)。

其他網路堆疊

應用程式也可以將其他網路堆疊與 ExoPlayer 整合。方法是實作包裝網路堆疊的 HttpDataSource。 以及對應的 HttpDataSource.FactoryExoPlayer 的 Cronet 和 OkHttp 程式庫是實際操作的範例。

與純 Java 網路堆疊整合時,建議您實作 DataSourceContractTest,以便檢查 HttpDataSource 實作項目的運作情形。OkHttp 程式庫中的 OkHttpDataSourceContractTest 就是一個很好的示例。

選擇網路堆疊

下表列出 ExoPlayer 支援的網路堆疊的優缺點。

網路堆疊 通訊協定 APK 大小影響 附註
HttpEngine 透過 QUIC 的 HTTP
HTTP/2
HTTP/3
僅適用於 API 34 或 S Extensions 7
Cronet (Google Play 服務) HTTP
HTTP/2
HTTP/3 over QUIC
小型
(小於 100 KB)
需要 Google Play 服務。Cronet 版本自動更新
Cronet (嵌入式) HTTP
HTTP/2
HTTP/3 over QUIC
大型
(約 8 MB)
應用程式開發人員控管的 Cronet 版本
Cronet (備用) HTTP
(因裝置而異)

(<100KB)
不建議用於 ExoPlayer
奧克拉荷馬州 HTTP
HTTP/2
小型
(<1MB)
內建網路堆疊 HTTP
(因裝置而異)
導入程序因裝置而異

透過 QUIC 通訊協定的 HTTP/2 和 HTTP/3 可大幅改善媒體串流效能。尤其是串流可自動調整媒體 只會透過內容發布聯播網 (CDN) 發布 這些通訊協定可讓 CDN 更有效率地運作。 因此,如果內容代管伺服器也支援這些通訊協定,HttpEngine 和 Cronet 在 QUIC 上支援 HTTP/2 和 HTTP/3 (以及 OkHttp 支援 HTTP/2),相較於使用 Android 內建的網路堆疊,這項功能是主要優勢。

在考慮單獨串流媒體時,建議您使用 Google Play 服務提供的 HttpEngine 或 Cronet,並在 Google Play 服務無法使用時改用 DefaultHttpDataSource。這項建議可在大多數裝置上使用 HTTP/2 和 HTTP/3 來取代 QUIC,並避免 APK 大小大幅增加。有些例外狀況 與建議可能無法使用 Google Play 服務的情況 可在大量執行應用程式的裝置上 或許更適合使用 Cronet Embedded 或 OkHttp。如果 APK 大小是重大問題,或是媒體串流只是應用程式功能的一小部分,那麼使用內建網路堆疊可能會是可接受的做法。

在一般情況下,建議除了媒體之外,最好選擇單一網路堆疊 適用於應用程式執行的所有網路這樣一來 以便有效率地在 ExoPlayer 和其他服務之間共用及共用通訊端 應用程式元件

由於您的應用程式很可能需要執行與媒體播放無關的網路功能,因此在選擇網路堆疊時,請務必考量上述針對媒體串流的建議 (單獨使用)、執行網路功能的任何其他元件的相關規定,以及這些元件相對於應用程式的相對重要性。

快取媒體

ExoPlayer 支援將已載入的位元組快取到磁碟,以免重複從網路載入相同的位元組。在目前媒體中倒轉或重複播放相同項目時,這項功能就非常實用。

快取功能需要 SimpleCache 例項,指向專屬快取目錄和 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();