Giao diện trình phát

Trình phát là một thành phần trong ứng dụng của bạn, hỗ trợ việc phát các mục nội dung đa phương tiện. Giao diện Media3 Player thiết lập đường viền cho chức năng thường do trình phát xử lý. Nội dung này bao gồm:

  • Ảnh hưởng đến các nút điều khiển chế độ phát, chẳng hạn như phát, tạm dừng và tua
  • Truy vấn các thuộc tính của nội dung nghe nhìn đang phát, chẳng hạn như vị trí phát
  • Quản lý danh sách phát/hàng đợi mục nội dung đa phương tiện
  • Định cấu hình các thuộc tính phát, chẳng hạn như phát ngẫu nhiên, lặp lại, tốc độ và âm lượng
  • Kết xuất video lên màn hình

Media3 cũng cung cấp phương thức triển khai giao diện Player, có tên là ExoPlayer.

Một giao diện chung giữa các thành phần

Một số thành phần trong Media3 triển khai giao diện Trình phát, ví dụ:

Thành phần Ghi chú về phần mô tả và hành vi
ExoPlayer API trình phát nội dung đa phương tiện và phương thức triển khai mặc định của giao diện Player.
MediaController Tương tác với MediaSession để gửi lệnh phát. Nếu PlayerMediaSession của bạn nằm trong Service, tách biệt với Activity hoặc Fragment nơi chứa giao diện người dùng của người chơi, thì bạn có thể chỉ định MediaController làm trình phát cho giao diện người dùng PlayerView. Các lệnh gọi phương thức phát và danh sách phát sẽ được gửi đến Player thông qua MediaSession.
MediaBrowser Ngoài chức năng do MediaController cung cấp, hãy tương tác với MediaLibrarySession để duyệt qua nội dung nghe nhìn hiện có.
ForwardingPlayer Hoạt động triển khai Player chuyển tiếp lệnh gọi phương thức đến một Player khác. Hãy sử dụng lớp này để chặn hoặc sửa đổi các thao tác cụ thể bằng cách ghi đè các phương thức tương ứng.
SimpleBasePlayer Việc triển khai Player giúp giảm số lượng phương thức cần triển khai đến mức tối thiểu. Hữu ích khi sử dụng trình phát tuỳ chỉnh mà bạn muốn kết nối với MediaSession.
CastPlayer Quá trình triển khai Player giao tiếp với ứng dụng receiver Cast. Hành vi phụ thuộc vào phiên Truyền cơ bản.

Mặc dù MediaSession không triển khai giao diện Player, nhưng bạn cần có Player khi tạo giao diện. Mục đích của lớp này là cung cấp quyền truy cập vào Player từ các quy trình hoặc luồng khác.

Cấu trúc phát Media3

Nếu có quyền truy cập vào Player, bạn nên gọi trực tiếp các phương thức của lớp đó để ra lệnh phát. Bạn có thể quảng cáo chế độ phát và cấp quyền kiểm soát phát các nguồn bên ngoài bằng cách triển khai MediaSession. Các nguồn bên ngoài này triển khai MediaController để hỗ trợ việc kết nối với một phiên phát nội dung đa phương tiện và đưa ra các yêu cầu lệnh phát.

Khi phát nội dung nghe nhìn trong nền, bạn cần đặt phiên phát nội dung đa phương tiện và trình phát trong MediaSessionService hoặc MediaLibraryService hoạt động dưới dạng dịch vụ trên nền trước. Nếu làm như vậy, bạn có thể tách trình phát khỏi Hoạt động trong ứng dụng chứa giao diện người dùng để điều khiển chế độ phát. Trong trường hợp này, bạn có thể phải sử dụng trình điều khiển nội dung đa phương tiện.

Sơ đồ cho thấy cách các thành phần phát Media3 phù hợp với cấu trúc ứng dụng đa phương tiện.
Hình 1: Giao diện Player đóng vai trò quan trọng trong cấu trúc của Media3.

Trạng thái trình phát

Trạng thái của trình phát nội dung đa phương tiện triển khai giao diện Player chủ yếu bao gồm 4 danh mục thông tin:

  1. Trạng thái phát
  2. Danh sách phát chứa các mục nội dung nghe nhìn
    • Một chuỗi gồm các thực thể MediaItem để phát.
    • Truy xuất bằng getCurrentTimeline()
    • Các thực thể Player có thể cung cấp các phương thức thao tác đối với danh sách phát như thêm hoặc xoá MediaItem và các phương thức tiện lợi như getCurrentMediaItem().
  3. Phát/tạm dừng các thuộc tính, chẳng hạn như:
    • playWhenReady: Chỉ báo cho biết người dùng muốn phát nội dung nghe nhìn khi có thể hay tiếp tục tạm dừng
    • Lý do chặn hoạt động phát: Cho biết lý do khiến tính năng phát bị chặn (nếu có), ngay cả khi playWhenReadytrue
    • isPlaying: Chỉ báo cho biết trình phát hiện có đang phát hay không. Giá trị này sẽ chỉ là true nếu trạng thái phát là STATE_READY, playWhenReadytrue và chế độ phát không bị chặn
  4. Vị trí phát, bao gồm:

Ngoài ra, giao diện Player cho phép truy cập vào các bản nhạc hiện có, siêu dữ liệu về nội dung nghe nhìn, tốc độ phát, âm lượng và các thuộc tính phụ khác của quá trình phát.

Nghe những thay đổi

Sử dụng Player.Listener để theo dõi các thay đổi trong Player. Xem tài liệu về ExoPlayer về Sự kiện trình phát để biết thông tin chi tiết về cách tạo và sử dụng trình nghe.

Xin lưu ý rằng giao diện trình nghe không bao gồm bất kỳ lệnh gọi lại nào để theo dõi tiến trình phát thông thường. Để liên tục theo dõi tiến trình phát, chẳng hạn như để thiết lập giao diện người dùng trên thanh tiến trình, bạn nên truy vấn vị trí hiện tại theo các khoảng thời gian thích hợp.

Kotlin

val handler = Handler(Looper.getMainLooper())
fun checkPlaybackPosition(delayMs: Long): Boolean =
  handler.postDelayed(
    {
      val currentPosition = player.currentPosition
      // Update UI based on currentPosition
      checkPlaybackPosition(delayMs)
    },
    delayMs)

Java

Handler handler = new Handler(Looper.getMainLooper());
boolean checkPlaybackPosition(long delayMs) {
    return handler.postDelayed(() -> {
        long currentPosition = player.getCurrentPosition();
        // Update UI based on currentPosition
        checkPlaybackPosition(delayMs);
    }, delayMs);
}

Điều khiển tính năng phát

Giao diện Player cung cấp nhiều cách để thao tác với trạng thái và kiểm soát quá trình phát:

Triển khai Player tuỳ chỉnh

Để tạo một trình phát tuỳ chỉnh, bạn có thể mở rộng SimpleBasePlayer có trong Media3. Lớp này cung cấp cách triển khai cơ sở của giao diện Player để giảm số lượng phương thức bạn cần triển khai ở mức tối thiểu.

Bắt đầu bằng cách ghi đè phương thức getState(). Phương thức này sẽ điền trạng thái trình phát hiện tại khi được gọi, bao gồm:

  • Tập hợp các lệnh hiện có
  • Các thuộc tính phát, chẳng hạn như trình phát có bắt đầu phát khi trạng thái phát là STATE_READY hay không, chỉ mục của mục nội dung đa phương tiện đang phát và vị trí phát trong mục hiện tại

Kotlin

class CustomPlayer : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(...) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build()
  }
}

Java

public class CustomPlayer extends SimpleBasePlayer {
  public CustomPlayer(Looper looper) {
    super(looper);
  }

  @Override
  protected State getState() {
    return new State.Builder()
      .setAvailableCommands(...) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build();
  }
}

SimpleBasePlayer sẽ thực thi State được tạo bằng một tổ hợp giá trị trạng thái hợp lệ. API này cũng sẽ xử lý trình nghe và thông báo cho trình nghe về các thay đổi trạng thái. Nếu bạn cần kích hoạt thao tác cập nhật trạng thái theo cách thủ công, hãy gọi invalidateState().

Ngoài phương thức getState(), bạn chỉ cần triển khai các phương thức dùng cho các lệnh mà trình phát của bạn khai báo là có sẵn. Tìm phương thức trình xử lý có thể ghi đè tương ứng với chức năng mà bạn muốn triển khai. Ví dụ: ghi đè phương thức handleSeek() để hỗ trợ các thao tác như COMMAND_SEEK_IN_CURRENT_MEDIA_ITEMCOMMAND_SEEK_TO_NEXT_MEDIA_ITEM.