Kết nối với một ứng dụng đa phương tiện

Có 2 cách để kết nối với một ứng dụng Đa phương tiện:

  1. MediaController
  2. MediaBrowser

MediaController

Trình điều khiển nội dung nghe nhìn tương tác với một phiên nội dung đa phương tiện để truy vấn và kiểm soát quá trình phát của ứng dụng đa phương tiện. Trong Media3, MediaController API triển khai giao diện Player. Một số ví dụ về ứng dụng khách sử dụng trình điều khiển nội dung đa phương tiện:

Trình điều khiển nội dung nghe nhìn cũng có thể hữu ích trong ứng dụng đa phương tiện, chẳng hạn như nếu trình phát và phiên nội dung đa phương tiện nằm trong Service tách biệt với Activity hoặc Fragment có giao diện người dùng.

Tạo MediaController

Để tạo MediaController, hãy bắt đầu bằng cách tạo SessionToken cho MediaSession tương ứng. Phương thức onStart() của Activity hoặc Fragment có thể là nơi phù hợp cho việc này.

Kotlin

val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))

Java

SessionToken sessionToken =
    new SessionToken(context, new ComponentName(context, PlaybackService.class));

Việc sử dụng SessionToken này để tạo MediaController sẽ kết nối bộ điều khiển với phiên đã cho. Quá trình này diễn ra không đồng bộ, vì vậy, bạn nên theo dõi kết quả và sử dụng kết quả đó khi có.

Kotlin

val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync()
controllerFuture.addListener(
  {
    // MediaController is available here with controllerFuture.get()
  },
  MoreExecutors.directExecutor(),
)

Java

ListenableFuture<MediaController> controllerFuture =
    new MediaController.Builder(context, sessionToken).buildAsync();
controllerFuture.addListener(
    () -> {
      // MediaController is available here with controllerFuture.get()
    },
    MoreExecutors.directExecutor());

Sử dụng MediaController

MediaController triển khai giao diện Player, vì vậy, bạn có thể sử dụng các lệnh được xác định trong giao diện để kiểm soát quá trình phát của MediaSession đã kết nối. Điều này có nghĩa là việc gọi play() trên MediaController sẽ gửi lệnh đến MediaSession đã kết nối, sau đó sẽ uỷ quyền lệnh cho Player cơ bản.

Bạn có thể thêm Player.Listener vào trình điều khiển để theo dõi các thay đổi về trạng thái Player. Hãy tham khảo hướng dẫn về các sự kiện của Trình phát để biết thêm thông tin chi tiết về cách sử dụng Player.Listener.

Giao diện MediaController.Listener xác định các lệnh gọi lại bổ sung cho các sự kiện và lệnh tuỳ chỉnh từ MediaSession đã kết nối. Ví dụ: onCustomCommand() khi phiên phát gửi một lệnh tuỳ chỉnh, onAvailableSessionCommandsChanged() khi phiên phát thay đổi các lệnh phiên phát có sẵn hoặc onDisconnected() khi trình điều khiển bị ngắt kết nối khỏi phiên phát.

Bạn có thể đặt MediaController.Listener khi tạo trình điều khiển bằng Builder:

Kotlin

val controllerFuture =
  MediaController.Builder(context, sessionToken)
    .setListener(
      object : MediaController.Listener {
        override fun onCustomCommand(
          controller: MediaController,
          command: SessionCommand,
          args: Bundle,
        ): ListenableFuture<SessionResult> {
          // Handle custom command.
          return Futures.immediateFuture(SessionResult(SessionResult.RESULT_SUCCESS))
        }

        override fun onDisconnected(controller: MediaController) {
          // Handle disconnection.
        }
      }
    )
    .buildAsync()

Java

ListenableFuture<MediaController> controllerFuture =
    new MediaController.Builder(context, sessionToken)
        .setListener(
            new MediaController.Listener() {
              @Override
              public ListenableFuture<SessionResult> onCustomCommand(
                  MediaController controller, SessionCommand command, Bundle args) {
                // Handle custom command.
                return Futures.immediateFuture(new SessionResult(SessionResult.RESULT_SUCCESS));
              }

              @Override
              public void onDisconnected(MediaController controller) {
                // Handle disconnection.
              }
            })
        .buildAsync();

Giống như các thành phần khác, hãy nhớ phát hành MediaController khi không còn cần đến nữa, chẳng hạn như trong phương thức onStop() của Activity hoặc Fragment.

Kotlin

MediaController.releaseFuture(controllerFuture)

Java

MediaController.releaseFuture(controllerFuture);

Việc phát hành trình điều khiển vẫn sẽ gửi tất cả các lệnh đang chờ xử lý được gửi đến phiên phát và chỉ huỷ liên kết khỏi dịch vụ phiên phát sau khi các lệnh này được xử lý hoặc sau một khoảng thời gian chờ, tuỳ theo điều kiện nào xảy ra trước.

MediaBrowser

MediaBrowser dựa trên các chức năng do MediaController cung cấp để cũng cho phép duyệt thư viện nội dung đa phương tiện do MediaLibraryService của ứng dụng đa phương tiện cung cấp.

Tạo MediaBrowser

Kotlin

val browserFuture = MediaBrowser.Builder(context, sessionToken).buildAsync()
browserFuture.addListener(
  {
    // MediaBrowser is available here with browserFuture.get()
  },
  MoreExecutors.directExecutor(),
)

Java

ListenableFuture<MediaBrowser> browserFuture =
    new MediaBrowser.Builder(context, sessionToken).buildAsync();
browserFuture.addListener(
    () -> {
      // MediaBrowser is available here with browserFuture.get()
    },
    MoreExecutors.directExecutor());

Sử dụng MediaBrowser

Để bắt đầu duyệt thư viện nội dung của ứng dụng đa phương tiện, trước tiên, hãy truy xuất nút gốc bằng getLibraryRoot():

Kotlin

// Get the library root to start browsing the library tree.
val rootFuture = mediaBrowser.getLibraryRoot(/* params= */ null)
rootFuture.addListener(
  {
    // Root node MediaItem is available here with rootFuture.get().value
  },
  MoreExecutors.directExecutor(),
)

Java

// Get the library root to start browsing the library tree.
ListenableFuture<LibraryResult<MediaItem>> rootFuture =
    mediaBrowser.getLibraryRoot(/* params= */ null);
rootFuture.addListener(
    () -> {
      // Root node MediaItem is available here with rootFuture.get().value
    },
    MoreExecutors.directExecutor());

Sau đó, bạn có thể di chuyển qua thư viện nội dung đa phương tiện bằng cách truy xuất các phần tử con của MediaItem trong thư viện bằng getChildren(). Ví dụ: để truy xuất các phần tử con của nút gốc MediaItem:

Kotlin

// Get the library root to start browsing the library tree.
val childrenFuture = mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Int.MAX_VALUE, null)
childrenFuture.addListener(
  {
    // List of children MediaItem nodes is available here with
    // childrenFuture.get().value
  },
  MoreExecutors.directExecutor(),
)

Java

ListenableFuture<LibraryResult<ImmutableList<MediaItem>>> childrenFuture =
    mediaBrowser.getChildren(rootMediaItem.mediaId, 0, Integer.MAX_VALUE, null);
childrenFuture.addListener(
    () -> {
      // List of children MediaItem nodes is available here with
      // childrenFuture.get().value
    },
    MoreExecutors.directExecutor());

Hiển thị nút điều khiển phát cho một ứng dụng đa phương tiện khác

Khi hiển thị các nút điều khiển giao diện người dùng cho một ứng dụng đa phương tiện khác, bạn cần tuân thủ các lựa chọn ưu tiên đã khai báo về nút nội dung đa phương tiện của ứng dụng đó.

Để giải quyết các lựa chọn ưu tiên của ứng dụng với các ràng buộc và yêu cầu của giao diện người dùng, hãy sử dụng CommandButton.DisplayConstraints. Bạn có thể xác định các giới hạn và hạn chế mà giao diện người dùng có thể thực hiện, đồng thời phương thức resolve cung cấp danh sách nút cụ thể để hiển thị cùng với biểu tượng, vị trí và hành động dự kiến. Nếu người dùng nhấp vào một trong các nút này, bạn có thể sử dụng CommandButton.executeAction để kích hoạt hành động được liên kết trong ứng dụng đa phương tiện.

Kotlin

// Get media button preferences from media app
val mediaButtonPreferences = controller.getMediaButtonPreferences()
// Declare constraints of UI (example: limit overflow button to one)
val displayConstraints =
  DisplayConstraints.Builder().setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1).build()
// Resolve media app preferences with constraints
val resolvedButtons = displayConstraints.resolve(mediaButtonPreferences, controller)
// Display buttons in UI
for (button in resolvedButtons) {
  generateUiButton(
    uiPosition = button.slots[0],
    icon = getIconRes(button.icon),
    onClick = { button.executeAction(controller) },
  )
}

Java

// Get media button preferences from media app
List<CommandButton> mediaButtonPreferences = controller.getMediaButtonPreferences();
// Declare constraints of UI (example: limit overflow button to one)
DisplayConstraints displayConstraints =
    new DisplayConstraints.Builder()
        .setMaxButtonsForSlot(CommandButton.SLOT_OVERFLOW, 1)
        .build();
// Resolve media app preferences with constraints
List<CommandButton> resolvedButtons =
    displayConstraints.resolve(mediaButtonPreferences, controller);
// Display buttons in UI
for (CommandButton button : resolvedButtons) {
  generateUiButton(
      /* uiPosition= */ button.slots.get(0),
      /* icon= */ getIconRes(button.icon),
      /* onClick= */ () -> button.executeAction(controller));
}