Thêm bộ điều khiển chế độ phát vào ứng dụng

Một ứng dụng phát nội dung nghe nhìn cần có các thành phần giao diện người dùng để hiển thị nội dung nghe nhìn và kiểm soát việc phát. Thư viện Media3 bao gồm một mô-đun giao diện người dùng chứa một số thành phần giao diện người dùng. Để phụ thuộc vào mô-đun giao diện người dùng, hãy thêm phần phụ thuộc sau:

Kotlin

implementation("androidx.media3:media3-ui:1.3.1")

Groovy

implementation "androidx.media3:media3-ui:1.3.1"

Thành phần quan trọng nhất là PlayerView, một khung hiển thị cho các lượt phát nội dung đa phương tiện. PlayerView hiển thị video, phụ đề và ảnh bìa đĩa nhạc trong khi phát, cũng như các bộ điều khiển chế độ phát.

PlayerView có phương thức setPlayer để đính kèm và tách rời (bằng cách truyền các thực thể người chơi null).

Chế độ xem trình phát

PlayerView có thể dùng cho cả lượt phát âm thanh và video. Tính năng này hiển thị video và phụ đề trong trường hợp phát video, đồng thời có thể hiển thị hình minh hoạ được đưa vào dưới dạng siêu dữ liệu trong tệp âm thanh. Bạn có thể đưa thành phần này vào tệp bố cục như mọi thành phần giao diện người dùng khác. Ví dụ: PlayerView có thể được đưa vào với XML sau đây:

<androidx.media3.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing"
    app:show_shuffle_button="true"/>

Đoạn mã trên minh hoạ rằng PlayerView cung cấp một số thuộc tính. Bạn có thể dùng các thuộc tính này để tuỳ chỉnh hành vi cũng như giao diện của thành phần hiển thị đó. Hầu hết các thuộc tính này đều có phương thức setter tương ứng, có thể dùng để tuỳ chỉnh khung hiển thị trong thời gian chạy. Javadoc PlayerView liệt kê các thuộc tính và phương thức setter này một cách chi tiết hơn.

Sau khi khai báo khung hiển thị trong tệp bố cục, bạn có thể tra cứu khung hiển thị trong phương thức onCreate của hoạt động:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView = findViewById(R.id.player_view)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // ...
  playerView = findViewById(R.id.player_view);
}

Sau khi khởi động trình phát, bạn có thể đính kèm trình phát vào khung hiển thị bằng cách gọi setPlayer:

Kotlin

// Instantiate the player.
val player = ExoPlayer.Builder(context).build()
// Attach player to the view.
playerView.player = player
// Set the media item to be played.
player.setMediaItem(mediaItem)
// Prepare the player.
player.prepare()

Java

// Instantiate the player.
player = new ExoPlayer.Builder(context).build();
// Attach player to the view.
playerView.setPlayer(player);
// Set the media item to be played.
player.setMediaItem(mediaItem);
// Prepare the player.
player.prepare();

Chọn một loại nền tảng

Thuộc tính surface_type của PlayerView cho phép bạn đặt loại nền tảng dùng để phát video. Bên cạnh các giá trị spherical_gl_surface_view (là một giá trị đặc biệt để phát video hình cầu) và video_decoder_gl_surface_view (dùng để kết xuất video bằng trình kết xuất tiện ích), các giá trị được phép là surface_view, texture_viewnone. Nếu khung hiển thị chỉ dành để phát âm thanh, bạn nên dùng none để tránh phải tạo một khu vực vì việc này có thể gây tốn kém.

Nếu khung hiển thị này là để phát video thông thường, thì bạn nên sử dụng surface_view hoặc texture_view. So với TextureView, SurfaceView có một số lợi ích về việc phát video:

  • Giảm đáng kể mức tiêu thụ pin trên nhiều thiết bị.
  • Thời gian kết xuất khung hình chính xác hơn, giúp video phát mượt mà hơn.
  • Hỗ trợ đầu ra video HDR chất lượng cao hơn trên các thiết bị có tính năng này.
  • Hỗ trợ đầu ra an toàn khi phát nội dung được bảo vệ bằng DRM.
  • Khả năng kết xuất nội dung video ở độ phân giải đầy đủ của màn hình trên các thiết bị Android TV giúp nâng cao lớp giao diện người dùng.

Do đó, SurfaceView nên được ưu tiên hơn TextureView nếu có thể. Bạn chỉ nên sử dụng TextureView nếu SurfaceView không đáp ứng nhu cầu của bạn. Một ví dụ là trường hợp bắt buộc phải sử dụng ảnh động mượt mà hoặc cuộn giao diện video trước Android 7.0 (API cấp 24), như mô tả trong các ghi chú sau. Trong trường hợp này, bạn chỉ nên sử dụng TextureView khi SDK_INT dưới 24 (Android 7.0) và SurfaceView.

Điều hướng bằng D-pad trên Android TV

Điều khiển từ xa của Android TV có bộ điều khiển D-pad gửi các lệnh đến dưới dạng sự kiện chính vào dispatchKeyEvent(KeyEvent) của Activity. Những tài nguyên này cần được uỷ quyền cho khung hiển thị trình phát:

Kotlin

override fun dispatchKeyEvent(event: KeyEvent?): Boolean{
  return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event)
}

Java

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}

Việc yêu cầu tiêu điểm cho chế độ xem trình phát là rất quan trọng để điều hướng các bộ điều khiển chế độ phát và bỏ qua quảng cáo. Hãy cân nhắc việc yêu cầu tiêu điểm trong onCreate/Activity:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView.requestFocus()
  // ...
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    playerView.requestFocus();
    // ...
}

Nếu đang sử dụng Compose trên Android TV, bạn cần làm cho AndroidView có thể làm tâm điểm và uỷ quyền sự kiện bằng cách truyền tham số đối tượng sửa đổi vào AndroidView cho phù hợp:

AndroidView(
  modifier = modifier
    .focusable()
    .onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
  factory = { playerView }
)

Ghi đè đối tượng có thể vẽ

PlayerView sử dụng PlayerControlView để hiển thị các nút điều khiển chế độ phát và thanh tiến trình. Các đối tượng có thể vẽ do PlayerControlView sử dụng có thể bị ghi đè bằng các đối tượng có thể vẽ có cùng tên được xác định trong ứng dụng của bạn. Hãy xem Javadoc PlayerControlView để biết danh sách các đối tượng điều khiển có thể vẽ có thể được ghi đè.

Tuỳ chỉnh thêm

Khi bắt buộc phải tuỳ chỉnh các thành phần mô tả ở trên, chúng tôi hy vọng rằng nhà phát triển ứng dụng sẽ triển khai các thành phần giao diện người dùng của riêng họ thay vì sử dụng các thành phần do mô-đun giao diện người dùng của Media3 cung cấp.