Membuat dan mengonfigurasi DefaultPreloadManager

Halaman ini menjelaskan cara membuat DefaultPreloadManager, yang memuat konten media untuk aplikasi Anda berdasarkan strategi yang Anda pilih.

Pengelola pra-muat berdasarkan class abstrak BasePreloadManager memungkinkan Anda memberi peringkat konten berdasarkan kriteria yang Anda pilih. Dokumen ini menjelaskan cara menggunakan class turunan DefaultPreloadManager, yang setiap item medianya diberi peringkat dengan bilangan bulat yang merepresentasikan lokasinya dalam daftar (misalnya, posisinya dalam carousel video). Pengelola pramuat memprioritaskan pemuatan item berdasarkan seberapa dekat item tersebut dengan item yang sedang diputar pengguna. Dengan begitu, jika pengguna beralih ke item lain, item baru dapat langsung diputar.

Ada tiga langkah untuk membuat instance DefaultPreloadManager:

  • Tentukan TargetPreloadStatusControl yang dapat dikueri oleh pengelola pra-muat untuk mengetahui apakah item media siap dimuat dan berapa banyak yang akan dimuat.
  • Buat builder yang akan Anda gunakan untuk membuat pengelola pramuat, dan untuk membuat objek ExoPlayer aplikasi Anda.
  • Gunakan builder untuk membuat pengelola pra-muat dengan memanggil metode build() builder.

Membuat kontrol status pramuat target

Saat membuat DefaultPreloadManager.Builder, Anda akan meneruskan objek kontrol status pramuat target yang Anda tentukan. Objek ini mengimplementasikan antarmuka TargetPreloadStatusControl. Saat pengelola pra-muat bersiap untuk memuat media, pengelola akan memanggil metode getTargetPreloadStatus() kontrol status Anda untuk menentukan apakah akan menyiapkan, memuat, atau menyimpan konten dalam cache untuk item media. Pemuatan memuat data media langsung ke buffer dalam memori pemutar, sehingga siap untuk pemutaran instan, sementara penyimpanan dalam cache menyimpan data media ke cache disk persisten untuk menghemat memori pemutar. Kontrol status dapat membalas dengan salah satu kode status berikut:

  • STAGE_SPECIFIED_RANGE_LOADED: Pengelola pra-muat harus memuat konten dari posisi awal yang ditentukan dan selama durasi yang ditentukan (diberikan dalam milidetik) ke dalam buffer dalam memori pemutar.
  • STAGE_SPECIFIED_RANGE_CACHED: Pengelola pemuatan awal harus meng-cache konten dari posisi awal yang ditentukan dan selama durasi yang ditentukan (diberikan dalam milidetik) ke cache disk.
  • STAGE_TRACKS_SELECTED: Pengelola pra-muat harus memuat dan memproses informasi jalur konten, lalu memilih jalur. Pengelola pra-muat belum boleh mulai memuat konten.
  • STAGE_SOURCE_PREPARED: Pengelola pra-muat harus menyiapkan sumber konten. Misalnya, jika metadata konten berada dalam file manifes terpisah, pengelola pramuat dapat mengambil dan mengurai manifes tersebut.
  • null: Pengelola pra-muat tidak boleh memuat konten atau metadata apa pun untuk item media tersebut.

Anda harus memiliki strategi untuk memutuskan jumlah konten yang akan dimuat untuk setiap item media. Dalam contoh ini, lebih banyak konten dimuat untuk item yang paling dekat dengan item yang sedang diputar. Jika pengguna memutar konten dengan indeks n, pengontrol akan menampilkan kode berikut:

  • Indeks n+1 (item media berikutnya): Muat 3000 md (3 detik) dari posisi awal default
  • Indeks n-1 (item media sebelumnya): Memuat 1000 md (1 detik) dari posisi awal default
  • Item media lain dalam rentang n-2 hingga n+2: Kembali PreloadStatus.TRACKS_SELECTED
  • Item media lainnya dalam rentang n-4 hingga n+4: Return PreloadStatus.SOURCE_PREPARED
  • Untuk semua item media lainnya, tampilkan 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
  }
}

Poin penting tentang kode

  • Anda akan meneruskan instance MyTargetPreloadStatusControl ke builder pengelola pra-muat saat Anda membuatnya.
  • currentPlayingIndex menyimpan indeks item media apa pun yang sedang diputar. Tugas aplikasi adalah menjaga agar nilai tersebut tetap terbaru.
  • Saat pengelola pramuat siap memuat konten, pengelola akan memanggil getTargetPreloadStatus dan meneruskan informasi peringkat yang Anda tentukan untuk item media yang sesuai. Dalam kasus DefaultPreloadManager, informasi peringkat tersebut adalah bilangan bulat, yang menentukan posisi item dalam carousel. Metode ini memilih kode yang akan ditampilkan dengan membandingkan indeks tersebut dengan indeks item yang saat ini dipilih.

Buat pengelola pramuat

Untuk membuat pengelola pramuat, Anda memerlukan DefaultPreloadManager.Builder. Builder tersebut dikonfigurasi dengan konteks saat ini dan kontrol status pra-pemuatan target aplikasi. Anda dapat membuat pengelola pramuat dengan semua konfigurasi default.

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

Builder juga menyediakan metode setter yang dapat Anda gunakan untuk menetapkan komponen kustom pengelola pra-muat.

Misalnya, Anda dapat menyesuaikan total byte buffer target untuk semua sumber media yang melakukan pra-pemuatan di DefaultPreloadManager, sehingga data yang telah dimuat sebelumnya tidak akan melebihi batas tersebut. Anda dapat mengonfigurasi batas tersebut menggunakan setPlayerTargetBufferBytes(String, int) pada DefaultLoadControl.Builder kustom dengan nama pemain "preload" dan meneruskan instance tersebut ke builder pengelola pramuat:

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

Meskipun metode setter builder pada dasarnya bersifat opsional untuk penyesuaian, jika Anda ingin meng-cache item media apa pun ke disk, Anda harus mengonfigurasi builder dengan Cache dengan memanggil setCache(). Jika tidak ada cache yang dikonfigurasi, upaya untuk menyimpan item media ke cache akan menyebabkan IllegalStateException.

Buat ExoPlayer untuk memutar item media yang telah dimuat sebelumnya

Selain menggunakan builder untuk membuat pengelola pramuat, Anda juga akan menggunakannya untuk membuat objek ExoPlayer yang digunakan aplikasi Anda untuk memutar konten, sehingga ExoPlayer membagikan komponen dengan benar ke pengelola pramuat. Anda tetap dapat menyetel konfigurasi khusus pemutaran untuk ExoPlayer dengan meneruskan instance ExoPlayer.Builder yang telah disetel konfigurasinya.

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

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