连接到媒体应用

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

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

创建 MediaController

要创建 MediaController,首先要为相应的 MediaSession 创建一个 SessionToken。在你的 ActivityFragmentonStart() 方法中执行此操作是一个好地方。

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