Tạo và định cấu hình DefaultPreloadManager

Trang này mô tả cách tạo một DefaultPreloadManager. này sẽ tải trước nội dung nghe nhìn cho ứng dụng của bạn dựa trên chiến lược mà bạn chọn.

Trình quản lý tải trước dựa trên lớp trừu tượng BasePreloadManager cho phép bạn xếp hạng nội dung theo tiêu chí mà bạn chọn. Tài liệu này giải thích cách sử dụng lớp dẫn xuất DefaultPreloadManager, trong đó mỗi mục nội dung nghe nhìn được xếp hạng bằng một số nguyên biểu thị vị trí của mục đó trong danh sách (ví dụ: vị trí của mục đó trong băng chuyền video). Trình quản lý tải trước ưu tiên tải các mục dựa trên mức độ gần với mục mà người dùng hiện đang phát. Bằng cách đó, nếu người dùng chuyển sang một mục khác, mục mới có thể bắt đầu phát ngay lập tức.

Có 3 bước để tạo một thực thể của DefaultPreloadManager:

  • Xác định một TargetPreloadStatusControl mà trình quản lý tải trước có thể truy vấn để biết liệu mục nội dung nghe nhìn đã sẵn sàng được tải hay chưa và cần tải bao nhiêu.
  • Tạo trình tạo mà bạn sẽ dùng để tạo trình quản lý tải trước và tạo các đối tượng ExoPlayer của ứng dụng.
  • Dùng trình tạo để tạo trình quản lý tải trước bằng cách gọi phương thức build() của trình tạo.

Tạo chế độ kiểm soát trạng thái tải trước mục tiêu

Khi tạo DefaultPreloadManager.Builder, bạn sẽ truyền cho đối tượng này một đối tượng kiểm soát trạng thái tải trước mục tiêu mà bạn xác định. Đối tượng này triển khai giao diện TargetPreloadStatusControl. Khi trình quản lý tải trước chuẩn bị tải trước nội dung nghe nhìn, trình quản lý này sẽ gọi phương thức getTargetPreloadStatus() của chế độ kiểm soát trạng thái để xác định xem có nên chuẩn bị, tải hoặc lưu nội dung vào bộ nhớ đệm cho một mục nội dung nghe nhìn hay không. Quá trình tải trước sẽ tải trực tiếp dữ liệu đa phương tiện vào vùng đệm trong bộ nhớ của trình phát, giúp dữ liệu sẵn sàng để phát tức thì, trong khi quá trình lưu vào bộ nhớ đệm sẽ lưu dữ liệu đa phương tiện vào bộ nhớ đệm của ổ đĩa liên tục để tiết kiệm bộ nhớ của trình phát. Thành phần kiểm soát trạng thái có thể trả lời bằng một trong những mã trạng thái sau:

  • STAGE_SPECIFIED_RANGE_LOADED: Trình quản lý tải trước sẽ tải nội dung từ vị trí bắt đầu đã chỉ định và trong khoảng thời gian đã chỉ định (tính bằng mili giây) vào vùng đệm trong bộ nhớ của trình phát.
  • STAGE_SPECIFIED_RANGE_CACHED: Trình quản lý tải trước sẽ lưu nội dung vào bộ nhớ đệm của ổ đĩa từ vị trí bắt đầu đã chỉ định và trong khoảng thời gian đã chỉ định (tính bằng mili giây).
  • STAGE_TRACKS_SELECTED: Trình quản lý tải trước phải tải và xử lý thông tin của bản nhạc nội dung, đồng thời chọn các bản nhạc. Trình quản lý tải trước chưa được bắt đầu tải nội dung.
  • STAGE_SOURCE_PREPARED: Trình quản lý tải trước phải chuẩn bị nguồn nội dung. Ví dụ: nếu siêu dữ liệu của nội dung nằm trong một tệp kê khai riêng, thì trình quản lý tải trước có thể tìm nạp và phân tích cú pháp tệp kê khai đó.
  • null: Trình quản lý tải trước không được tải bất kỳ nội dung hoặc siêu dữ liệu nào cho mục nội dung nghe nhìn đó.

Bạn cần có một chiến lược để quyết định lượng nội dung cần tải cho mỗi mục nội dung nghe nhìn. Trong ví dụ này, nhiều nội dung hơn được tải cho những mục gần với mục đang phát nhất. Nếu người dùng đang phát nội dung có chỉ mục n, thì bộ điều khiển sẽ trả về các mã sau:

  • Chỉ mục n+1 (mục nội dung nghe nhìn tiếp theo): Tải 3000 mili giây (3 giây) từ vị trí bắt đầu mặc định
  • Chỉ mục n-1 (mục nội dung nghe nhìn trước đó): Tải 1000 mili giây (1 giây) từ vị trí bắt đầu mặc định
  • Các mục nội dung nghe nhìn khác trong phạm vi n-2 đến n+2: Return PreloadStatus.TRACKS_SELECTED
  • Các mục nội dung nghe nhìn khác trong phạm vi n-4 đến n+4: Trả về PreloadStatus.SOURCE_PREPARED
  • Đối với tất cả các mục nội dung nghe nhìn khác, hãy trả về 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
  }
}

Các điểm chính về mã

  • Bạn sẽ truyền một thực thể của MyTargetPreloadStatusControl đến trình tạo trình quản lý tải trước khi tạo thực thể đó.
  • currentPlayingIndex chứa chỉ mục của mục nội dung đa phương tiện đang phát. Ứng dụng có nhiệm vụ cập nhật giá trị đó.
  • Khi trình quản lý tải trước đã sẵn sàng tải nội dung, trình quản lý này sẽ gọi getTargetPreloadStatus và truyền thông tin xếp hạng mà bạn đã chỉ định cho mục nội dung nghe nhìn tương ứng đó. Trong trường hợp DefaultPreloadManager, thông tin xếp hạng đó là một số nguyên, chỉ định vị trí của mặt hàng trong một băng chuyền. Phương thức này chọn mã cần trả về bằng cách so sánh chỉ mục đó với chỉ mục của mục hiện được chọn.

Tạo trình quản lý tải trước

Để tạo trình quản lý tải trước, bạn cần có một DefaultPreloadManager.Builder. Trình tạo đó được định cấu hình bằng ngữ cảnh hiện tại và chế độ kiểm soát trạng thái tải trước mục tiêu của ứng dụng. Bạn có thể tạo một trình quản lý tải trước với tất cả các cấu hình mặc định.

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

Trình tạo này cũng cung cấp các phương thức setter mà bạn có thể dùng để thiết lập các thành phần tuỳ chỉnh của trình quản lý tải trước.

Ví dụ: bạn có thể tuỳ chỉnh tổng số byte đệm mục tiêu cho tất cả các nguồn nội dung nghe nhìn tải trước trong DefaultPreloadManager, để dữ liệu được tải trước sẽ không vượt quá giới hạn đó. Bạn có thể định cấu hình giới hạn đó bằng cách sử dụng setPlayerTargetBufferBytes(String, int) trên một DefaultLoadControl.Builder tuỳ chỉnh có tên người chơi "preload" và chuyển phiên bản đó đến trình tạo trình quản lý tải trước:

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

Mặc dù các phương thức setter của trình tạo về cơ bản là không bắt buộc để tuỳ chỉnh, nhưng nếu muốn lưu vào bộ nhớ đệm mọi mục nội dung nghe nhìn vào đĩa, bạn phải định cấu hình trình tạo bằng một Cache bằng cách gọi setCache(). Nếu không có bộ nhớ đệm nào được định cấu hình, thì việc cố gắng lưu vào bộ nhớ đệm các mục nội dung nghe nhìn sẽ dẫn đến IllegalStateException.

Tạo ExoPlayer để phát mục nội dung nghe nhìn được tải trước

Ngoài việc dùng trình tạo để tạo trình quản lý tải trước, bạn cũng sẽ dùng trình tạo này để tạo các đối tượng ExoPlayer mà ứng dụng của bạn dùng để phát nội dung, sao cho ExoPlayer chia sẻ các thành phần với trình quản lý tải trước một cách chính xác. Bạn vẫn có thể đặt các cấu hình phát cụ thể cho ExoPlayer bằng cách truyền một thực thể ExoPlayer.Builder có các cấu hình đó được đặt.

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

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