網路堆疊

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) 來源。

以下範例說明如何建構將使用 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 也可支援任何 就適合在 Android 上運作的其他網路堆疊

HttpEngine

HttpEngine 是 Android 中從 API 34 (或 S) 建議的預設網路堆疊 擴充功能 7)。在大多數情況下,它是在內部使用 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 服務:建議您在大部分 並改回使用 Android 內建的網路堆疊 (DefaultHttpDataSource) Google Play 服務無法使用。
  2. Cronet 嵌入:如果使用者有大量使用者,這項做法就很適合 Google Play 服務尚未普及的市場 和想要控制目前所用 Cronet 實作的確切版本。 Cronet Embedded 的主要缺點是,這個 API 會增加大約 8 MB
  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 服務) 透過 QUIC 的 HTTP
HTTP/2
HTTP/3
小型
(小於 100 KB)
需要 Google Play 服務。已自動更新 Cronet 版本
Cronet (內嵌) 透過 QUIC 的 HTTP
HTTP/2
HTTP/3

(約 8 MB)
應用程式開發人員控管的 Cronet 版本
Cronet (備用) HTTP
(因裝置而異)
小型
(小於 100 KB)
不建議用於 ExoPlayer
奧克拉荷馬州 HTTP
HTTP/2
小型
(小於 1 MB)
內建網路堆疊 HTTP
(因裝置而異)
導入程序因裝置而異

透過 QUIC 通訊協定的 HTTP/2 和 HTTP/3 可大幅提升媒體品質 串流效能。尤其是串流可自動調整媒體 只會透過內容發布聯播網 (CDN) 發布 這些通訊協定可讓 CDN 更有效率地運作。 因此,HttpEngine 和 Cronet 同時支援 HTTP/2 和 HTTP/3 遠比 QUIC (以及 OkHttp 支援的 HTTP/2 支援) 高出許多 使用 Android 內建的網路堆疊 代管內容也支援這些通訊協定。

如要單獨評估媒體串流,建議使用 HttpEngine 或 Google Play 服務提供的 Cronet 改回 DefaultHttpDataSource 就無法使用 Google Play 服務。這項建議的做法不錯 在大多數裝置上啟用 HTTP/2 和 HTTP/3 兩者之間的平衡 避免 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();