连接到媒体应用

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

媒体控制器在媒体应用中也很有用,例如,如果播放器和媒体会话位于与界面一起使用的 ActivityFragment 之外的 Service 中。

创建 MediaController

如需创建 MediaController,请先为SessionToken 相应的 MediaSessionActivityFragmentonStart() 方法是一个不错的选择。

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

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

KotlinJava
val controllerFuture =
  MediaController.Builder(context, sessionToken).buildAsync()
controllerFuture.addListener({
  // MediaController is available here with controllerFuture.get()
}, MoreExecutors.directExecutor())
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.ListenerMediaController.Listener 接口定义了来自 已连接 MediaSession,例如 onAvailableSessionCommandsChanged() 当媒体会话更改可用会话命令时 onDisconnected() 在控制器与会话断开连接时触发

与其他组件一样,在 MediaController 例如在 ActivityonStop() 方法中,或 Fragment

KotlinJava
MediaController.releaseFuture(controllerFuture)
MediaController.releaseFuture(controllerFuture);

释放控制器后,系统仍会传送发送到会话的所有待处理命令,并且仅在处理完这些命令或超时期限结束后(以先到者为准)解除与会话服务的绑定。

创建和使用 MediaBrowser

MediaBrowser基于 MediaController,还可以浏览媒体提供的媒体库 应用的 MediaLibraryService

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

如需开始浏览媒体应用的内容库,请先使用 getLibraryRoot() 检索根节点:

KotlinJava
// 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())
// 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 的子节点:

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