建立及設定 DefaultPreloadManager

本頁說明如何建立 DefaultPreloadManager,根據您選擇的策略預先載入應用程式的媒體內容。

您可以根據 BasePreloadManager 抽象類別預先載入管理員,並依所選條件對內容進行排序。本文說明如何使用衍生類別 DefaultPreloadManager,其中每個媒體項目都會以整數表示在清單中的位置 (例如在影片輪播中的位置)。預先載入管理工具會根據項目與使用者目前播放項目的距離,決定載入項目的優先順序。這樣一來,使用者移至其他項目時,新項目就能立即開始播放。

建立 DefaultPreloadManager 例項的步驟如下:

  • 定義 TargetPreloadStatusControl,預先載入管理工具可查詢該項目,瞭解媒體項目是否已準備好載入,以及要載入多少內容。
  • 建立建構工具,用於建立預先載入管理工具,以及建立應用程式的 ExoPlayer 物件。
  • 使用建構工具呼叫建構工具的 build() 方法,建立預先載入管理工具。

建立目標預先載入狀態控制項

建立 DefaultPreloadManager.Builder 時,您會將定義的目標預先載入狀態控制項物件傳遞給該物件。這個物件會實作 TargetPreloadStatusControl 介面。預先載入管理工具準備預先載入媒體時,會呼叫狀態控制項的 getTargetPreloadStatus() 方法,判斷是否要準備、載入或快取媒體項目的內容。載入功能會將媒體資料直接預先載入播放器的記憶體內緩衝區,以便立即播放,而快取功能則會將媒體資料儲存至永久磁碟快取,以節省播放器記憶體。狀態控制項可回覆下列其中一個狀態碼:

  • STAGE_SPECIFIED_RANGE_LOADED:預先載入管理工具應從指定開始位置載入內容,並在指定時間長度 (以毫秒為單位) 內,將內容載入播放器的記憶體緩衝區。
  • STAGE_SPECIFIED_RANGE_CACHED:預先載入管理工具應從指定開始位置快取內容,並將指定時間長度 (以毫秒為單位) 的內容快取到磁碟快取。
  • STAGE_TRACKS_SELECTED:預先載入管理工具應載入及處理內容軌的資訊,並選取軌。預先載入管理工具還不應開始載入內容。
  • STAGE_SOURCE_PREPARED:預先載入管理工具應準備內容來源。舉例來說,如果內容的中繼資料位於獨立資訊清單檔案中,預先載入管理工具可能會擷取並剖析該資訊清單。
  • null:預先載入管理工具不應載入該媒體項目的任何內容或中繼資料。

您需要制定策略,決定每個媒體項目要載入多少內容。在這個範例中,系統會為最接近目前播放項目的項目載入更多內容。如果使用者播放的內容索引為 n,控制器會傳回下列程式碼:

  • 索引 n+1 (下一個媒體項目):從預設起始位置載入 3000 毫秒 (3 秒)
  • 索引 n-1 (上一個媒體項目):從預設開始位置載入 1000 毫秒 (1 秒)
  • 範圍 n-2n+2 中的其他媒體項目:傳回 PreloadStatus.TRACKS_SELECTED
  • 範圍 n-4n+4 中的其他媒體項目:傳回 PreloadStatus.SOURCE_PREPARED
  • 如為所有其他媒體項目,請傳回 null

class MyTargetPreloadStatusControl(var currentPlayingIndex: Int = 0) :
  TargetPreloadStatusControl<Int, DefaultPreloadManager.PreloadStatus> {

  override fun getTargetPreloadStatus(index: Int): DefaultPreloadManager.PreloadStatus {
    if (index - currentPlayingIndex == 1) { // next track
      // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and
      // suggest loading 3000ms from the default start position
      return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L)
    } else if (index - currentPlayingIndex == -1) { // previous track
      // return a PreloadStatus that is labelled by STAGE_SPECIFIED_RANGE_LOADED and
      // suggest loading 3000ms from the default start position
      return DefaultPreloadManager.PreloadStatus.specifiedRangeLoaded(3000L)
    } else if (abs(index - currentPlayingIndex) == 2) {
      // return a PreloadStatus that is labelled by STAGE_TRACKS_SELECTED
      return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_TRACKS_SELECTED
    } else if (abs(index - currentPlayingIndex) <= 4) {
      // return a PreloadStatus that is labelled by STAGE_SOURCE_PREPARED
      return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_SOURCE_PREPARED
    }
    return DefaultPreloadManager.PreloadStatus.PRELOAD_STATUS_NOT_PRELOADED
  }
}

程式碼重點

  • 建立預先載入管理工具建構工具時,您會將 MyTargetPreloadStatusControl 的執行個體傳遞至該工具。
  • currentPlayingIndex 包含目前播放的媒體項目索引。應用程式的職責是確保該值為最新狀態。
  • 預先載入管理工具準備好載入內容時,會呼叫 getTargetPreloadStatus,並傳遞您為相應媒體項目指定的排名資訊。如果是 DefaultPreloadManager,這項排名資訊是整數,指定項目在輪播中的位置。這個方法會比較該索引與目前所選項目的索引,然後選擇要傳回的程式碼。

建立預先載入管理工具

如要建立預先載入管理工具,您需要 DefaultPreloadManager.Builder。 該建構工具已設定目前的內容,以及應用程式的目標預先載入狀態控制項。您可以建立預先載入管理工具,並使用所有預設設定。

val targetPreloadStatusControl = MyTargetPreloadStatusControl()
val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl)
val preloadManager = preloadManagerBuilder.build()

建構工具也提供設定器方法,可用於設定預先載入管理工具的自訂元件。

舉例來說,您可以自訂 DefaultPreloadManager 中所有預先載入媒體來源的目標緩衝區位元組總數,確保預先載入的資料不會超過該限制。您可以在自訂 DefaultLoadControl.Builder 上使用 setPlayerTargetBufferBytes(String, int) 設定該限制,並傳遞至預先載入管理工具建構工具:"preload"

val targetPreloadStatusControl = MyTargetPreloadStatusControl()
val preloadManagerBuilder = DefaultPreloadManager.Builder(context, targetPreloadStatusControl)

preloadManagerBuilder.setLoadControl(
  DefaultLoadControl.Builder()
    .setPlayerTargetBufferBytes("preload", 128 * 1024 * 1024) // 128 MiB
    .build()
)
val preloadManager = preloadManagerBuilder.build()

雖然建構工具的設定器方法基本上是自訂選項,但如要將任何媒體項目快取至磁碟,就必須透過呼叫 setCache(),使用 Cache 設定建構工具。如未設定快取,嘗試快取媒體項目會導致 IllegalStateException

建立 ExoPlayer,播放預先載入的媒體項目

除了使用建構工具建立預先載入管理工具,您還會使用該工具建立應用程式用來播放內容的 ExoPlayer 物件,確保 ExoPlayer 正確地與預先載入管理工具共用元件。您仍可傳遞已設定這些設定的 ExoPlayer.Builder 執行個體,為 ExoPlayer 設定播放專屬設定。

// Direct creation
val exoPlayer = preloadManagerBuilder.buildExoPlayer()

// Creation with custom playback specific configurations
val skipSilenceExoPlayerBuilder = ExoPlayer.Builder(context).setSkipSilenceEnabled(true)
val skipSilenceExoPlayer = preloadManagerBuilder.buildExoPlayer(skipSilenceExoPlayerBuilder)