连接媒体应用

媒体控制器与媒体会话交互以查询和控制媒体应用的播放。在 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());

然后,您可以通过检索库中 MediaItem 的子项来浏览媒体库,方法是使用 getChildren()。例如,要检索根节点 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());