连接到媒体应用

媒体控制器与媒体会话交互,以查询和控制媒体应用的播放。在 Media3 中,MediaController API 实现了 Player 接口。使用媒体控制器的客户端应用示例包括:

媒体控制器在媒体应用中也很有用,例如,如果播放器和媒体会话位于与界面的 ActivityFragment 分开的 Service 中,则媒体控制器也很有用。

创建 MediaController

如需创建 MediaController,请先为相应的 MediaSession 创建 SessionTokenActivityFragmentonStart() 方法很适合执行该操作。

Kotlin

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

Java

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

然后,使用此 SessionToken 构建 MediaController 可将控制器连接到给定会话。此操作是异步发生的,因此您应该监听结果并在可用时使用结果。

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

使用 MediaController

MediaController 会实现 Player 接口,因此您可以使用该接口中定义的命令来控制已连接的 MediaSession 的播放。也就是说,对 MediaController 调用 play() 会将该命令发送给连接的 MediaSession,随后后者会将该命令委托给其底层 Player

同样,您可以向控制器添加 Player.Listener 以监听 Player 状态的变化。如需详细了解如何使用 Player.Listener,请参阅玩家事件指南。MediaController.Listener 接口定义了针对已连接 MediaSession 的事件和传入命令的其他回调,例如,为 onAvailableSessionCommandsChanged() 定义媒体会话更改可用会话命令时的回调,以及针对控制器与会话断开连接时使用的 onDisconnected() 进行定义。

与其他组件一样,请记住在不再需要 MediaController 时将其释放,例如在 ActivityFragmentonStop() 方法中。

Kotlin

MediaController.releaseFuture(controllerFuture)

Java

MediaController.releaseFuture(controllerFuture);

释放控制器仍会传递发送到会话的所有待处理命令,并且仅会在命令处理完毕后或超时期限过后(二者取其先)解除与会话服务的绑定。

创建和使用 MediaBrowser

MediaBrowser 建立在 MediaController 提供的功能之上,还支持浏览媒体应用的 MediaLibraryService 提供的媒体库。

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

如需开始浏览媒体应用的内容库,请先使用 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());

然后,您可以使用 getChildren() 检索库中 MediaItem 的子项,从而在媒体库中导航。例如,如需检索根节点 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());