本頁說明如何建立 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-2 到 n+2 中的其他媒體項目:傳回
PreloadStatus.TRACKS_SELECTED - 範圍 n-4 到 n+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)