Android MediaBrowser 各组件使用概览

Posted Chin_style

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MediaBrowser 各组件使用概览相关的知识,希望对你有一定的参考价值。

一,前期基础知识储备

如何快速开发一款音频应用?基于已有的合作应用进行开发,比如百度的车载Carlife系统对QQ音乐,喜马拉雅等的调用。 音乐应用被第三方的android app打开,并获取其中的歌单,曲目列表,同时控制其播放。

Spotify - 一家在线音乐流服务平台,和其合作的厂商也是采用这种实现方式,官方SDK说明如下:

The Spotify SDK allows your application to interact with the Spotify app running in the background as a service. The capabilities of this API include getting metadata for the currently playing track and context, issuing basic playback commands and initiating playback of tracks.

合作方开发一个客户端应用,与作为服务端的Spotify进行交互,获取播放条目,并控制播放状态。

通俗一点,就是自己开发一个应用,作为一个进程,Spotify播放器是一个应用,作为一个进程,然后通过客户端/服务器设计,实现一个进程控制另一个进程的播放状态。

这种实现方式就是使用Android中的MediaBrowser与MediaBrowserService,Android官方文档

MediaBrowserService 提供两个主要功能:

  1. 当您使用 MediaBrowserService 时,具有 MediaBrowser 的其他组件和应用可以发现您的服务,创建自己的媒体控制器,连接到您的媒体会话,并控制播放器。Wear OS 和 Android Auto 应用才得以访问您的媒体应用。
  2. 此外,它还提供了一个可选的 Browsing API。应用可以不使用此功能。通过 Browsing API,客户端可以查询服务并构建其内容层次结构的表示,这可能表示播放列表、媒体库或其他类型的集合。

二,上代码,具体实现

Client需要创建MediaBrowser,Server需要实现MediaBrowserService,在建⽴连接后,两端之间的交互主要通过MediaController和MediaSession。两个类之间通过预先定义的callback进⾏交互,
MediaSession控制着播放器的播放,MediaController来控制着UI的变化。

实现具体分三步:

1. 构建媒体浏览器服务
说明了如何创建包含媒体会话的媒体浏览器服务,管理客户端连接以及在播放音频时成为前台服务。
2. 构建媒体浏览器客户端
说明了如何创建包含界面和媒体控制器的媒体浏览器客户端 Activity,以及如何与媒体浏览器服务进行连接和通信。
3. 媒体会话回调
说明了媒体会话回调方法如何管理媒体会话、媒体浏览器服务以及其他应用组件(如通知和广播接收器)。

1. 构建媒体浏览器服务

该步骤通常在播放器内部实现,客户端不必关注,客户端只需调用创建好的服务即可。

1)声明Service

必须在其清单中声明带有 Intent 过滤器的 MediaBrowserService。

    <service android:name=".MediaPlaybackService">
      <intent-filter>
        <action android:name="android.media.browse.MediaBrowserService" />
      </intent-filter>
    </service>

2)初始化媒体会话
当服务收到 onCreate() 生命周期回调方法时,它应该执行以下步骤:

  • 创建并初始化媒体会话
  • 设置媒体会话回调
  • 设置媒体会话令牌

3)管理客户端连接
MediaBrowserService 有两个方法来处理客户端连接:onGetRoot() 控制对服务的访问,onLoadChildren() 使客户端能够构建和显示 内容层次结构菜单。

2. 构建媒体浏览器客户端

  • 说明了如何创建包含界面和媒体控制器的媒体浏览器客户端 Activity

  • 以及如何与媒体浏览器服务进行连接和通信。

要完成客户端/服务器设计,您必须构建包含界面代码、关联的 MediaController 和 MediaBrowser 的 Activity 组件。

MediaBrowser 执行两项重要功能:

  • 连接到 MediaBrowserService;

  • 并在连接后为您的界面创建 MediaController。

1)连接到 MediaBrowserService

创建客户端 Activity 后,它会连接到 MediaBrowserService。这里涉及一点握手和跳跃。修改 Activity 的生命周期回调,如下所示:

  • onCreate() 构造 MediaBrowserCompat。传入 MediaBrowserService 的名称和已定义的 MediaBrowserCompat.ConnectionCallback

  • onStart() 连接到 MediaBrowserService。这里体现了 MediaBrowserCompat.ConnectionCallback 的神奇之处。如果连接成功,onConnect() 回调会创建媒体控制器,将其链接到媒体会话,将您的界面控件链接到 MediaController,并注册控制器以接收来自媒体会话的回调。

  • onResume() 设置音频流,以便您的应用响应设备上的音量控制。

  • onStop() 断开 MediaBrowser 的连接,并在 Activity 停止时取消注册 MediaController.Callback。

2)自定义 MediaBrowserCompat.ConnectionCallback

当您的 Activity 构造 MediaBrowserCompat 时,您必须创建 ConnectionCallback 的实例。修改其 onConnected() 方法以从 MediaBrowserService 检索媒体会话令牌,并使用该令牌创建 MediaControllerCompat

    private void connectToSession(MediaSessionCompat.Token token) throws RemoteException 
        // MediaSessionCompat 与 MediaControllerCompat 关联
        mMediaController = new MediaControllerCompat(mContext, token);
        // 音频变化监听
        mMediaController.registerCallback(mMediaControllerCallback);
        // 获取TransportControls 执行play pause next pre操作
        mTransportControls = mMediaController.getTransportControls();
        MediaMetadataCompat metadata = mMediaController.getMetadata();
        PlaybackStateCompat pbState = mediaController.getPlaybackState();
    

3)将界面连接到媒体控制器

MediaControllerCompat.TransportControls mTransportControls;
mTransportControls = mMediaController.getTransportControls();

TransportControls 方法向服务的媒体会话发送回调。确保为每个控件定义了相应的 MediaSessionCompat.Callback 方法。

4)与媒体会话保持同步

界面应显示媒体会话的当前状态(通过其 PlaybackState 和元数据来描述)。
要在媒体会话的状态或元数据每次发生更改时从媒体会话接收回调,请使用以下两种方法定义
 

媒体控制器,在客户端中开发者不仅可以使用控制器向Service中的媒体会话发送指令,还可以通过设置MediaControllerCompat.Callback回调方法接收媒体会话的状态,从而根据相应的状态刷新界面UI。MediaController的创建需要媒体会话的配对令牌,因此需在浏览器成功连接服务的回调执行创建的操作。

3. 媒体会话回调

您的媒体会话回调调用多个 API 中的方法来控制播放器,管理音频焦点以及与媒体会话和媒体浏览器服务通信。请注意,响应回调的 MediaSession 逻辑必须保持一致。回调的行为不得依赖于调用方的身份,该调用方可能是运行 MediaSession 的同一应用中的 Activity,也可能是任何其他带有已连接到 MediaSession 的 MediaController 应用中的 Activity。

    MediaSessionCompat.Callback callback = new
        MediaSessionCompat.Callback() 
            @Override
            public void onPlay() 
            public void onStop() 
            public void onPause() 
			public void onSkipToNext()
			public void onSkipToPrevious()
			public void onSeekTo(long pos) 
			public void onFastForward()
			public void onRewind()
			public void onSetRepeatMode(int repeatMode)
			... ...
        ;

通过设置MediaSessionCompat.Callback回调来接收媒体控制器MediaController发送的指令。当收到指令时会触发Callback中各个指令对应的回调方法(回调方法中会执行播放器相应的操作,如播放、暂停等)。

最后总结一下:

使用的关键类:

  •  MediaBrowserServiceCompat 媒体浏览器服务
  •  MediaBrowserCompat 媒体浏览器
  •  MediaControllerCompat 媒体控制器
  •  MediaSessionCompat 媒体会话

关键流程梳理:

  1. MediaBrowserServiceCompat继承自Service,为运行在后台的音频服务;
  2. MediaBrowserCompat 运行于前台,通过MediaSessionCompat与MediaBrowserServiceCompat建立连接,从而获取到一个MediaControllerCompat用于控制前台音频播放;
  3. MediaControllerCompat UI界面控制音频播放进度、播放速度、上一曲、下一曲音频播放等等;
  4. MediaSessionCompat - 运行于后台的MediaBrowserServiceCompat与运行于前台的MediaBrowserCompat通过MediaSessionCompat来建立连接;
  5. MediaSessionCompat.Callback 用户通过MediaControllerCompat对UI的操作,会通过MediaSessionCompat.Callback 回调到Service端,来操纵“播放器”进行播放、暂停、快进、上一曲、下一曲等操作;
  6. MediaControllerCompat.Callback Service端播放器播放完成、播放下一曲等操作,通过MediaControllerCompat.Callback回调到UI页面,操纵UI的变化。

官方项目示例:android-MediaBrowserService

一个MediaBrowser开源项目 Android_MediaBrowser_Demo -可以验证上述播放流程

参考文章:

MediaBrowserCompat MediaBrowserServiceCompat

Android 媒体播放框架MediaSession分析与实践

Android基于MediaBroswerService的App实现概述

以上是关于Android MediaBrowser 各组件使用概览的主要内容,如果未能解决你的问题,请参考以下文章

Android MediaBrowser 各组件使用概览

Android MediaBrowser 各组件使用概览

从活动 2(6.0.1 Android)返回活动 1 后,MediaBrowser.subscribe 不起作用

为啥连接到 mediaBrowser 时没有调用 connectionCallback.onConnected()?

致命异常:MediaBrowser 中的 java.lang.IllegalStateException

UAMP MediaBrowser 方向