Android MediaSession框架简析

一、简介

Google官方在 Android 5.0 引入的媒体应用框架,分为媒体控制器(用于UI)和媒体会话(用于播放器),主要目的是解耦UI和播放器(MediaPlayer、ExoPlayer等)。

controller-and-session

媒体控制器会隔离UI,将控制操作转换为对媒体会话的回调。当会话状态发生变化时,它也会接收来自媒体会话的回调。媒体控制器一次只能连接到一个媒体会话。

媒体会话负责与播放器的所有通信,它会对应用隐藏播放器的API,只能从控制播放器的媒体会话中调用播放器。它可以接收来自一个或多个媒体控制器的回调。

 

二、应用

1. 音频播放

音频应用对UI使用Activity,对播放器使用Service。如果用户切换到其他App,该服务可以在后台运行,响应一些媒体控制事件。通过将音频应用的UI和播放分解为单独的组件,每个组件都可以更高效地独立运行。

é³é¢ Activity å BrowserService

2. 视频播放

视频应用需要一个窗口来查看内容,通常使用单个Activity来实现。由于视频不需要在后台播放,所以不需要MediaBrowser、MediaBrowserService等类。

è§é¢æ­æ¾å¨ Activity

 

三、原理

1. 核心成员类

  • MediaBrowserCompat媒体浏览器客户端类。用于连接MediaBrowserServiceCompat和订阅媒体数据,在回调了连接成功的方法后,通过获取的token得到MediaControllerCompat对象。

  • MediaBrowserServiceCompat浏览器服务服务端类。作为承载实际的播放器和MediaSessionCompat的容器,一般在onCreate()方法中,用setSessionToken(...)来设置token。在重写的onGetRoot(…)方法中判断是否允许连接,在onLoadChildren(…)方法中处理订阅信息。

  • MediaControllerCompat媒体控制器客户端类。可以通过getMetadata()的方式主动获取媒体信息,也可以通过getTransportControls().xxx()的方式发送控制指令,在MediaControllerCompat.Callback中接收媒体的状态,从而刷新界面UI。

  • MediaSessionCompat媒体会话服务端类。通过MediaSessionCompat.Callback来接收MediaControllerCompat发送的指令,然后调用实际的播放器执行相应的操作,如播放、暂停等。在媒体信息或状态发生变化后,通过setMetadata(mediaMetadata)的方式通知客户端,即MediaControllerCompat.Callback中的onMetadataChanged(metadata)方法 。

2. 辅助成员类

  • PlaybackStateCompat: 播放状态类。封装了媒体的各类状态信息,主要是: 状态、进度。

  • MediaMetadataCompat: 构建媒体信息类。主要是:标题、作者、专辑名、总时长等。注意与MediaSessionCompat.QueueItem、MediaBrowserCompat.MediaItem之间的差异。

  • MediaDescriptionCompat: 解析媒体信息类。与MediaMetadataCompat的作用相对应。

3. 连接订阅

4. 数据加载

5. 媒体控制

 

 

参考:

https://developer.android.google.cn/guide/topics/media

https://www.jianshu.com/p/a6c2a3ed842d

https://blog.youkuaiyun.com/weixin_42229694/article/details/89315026

https://www.jianshu.com/p/dae43c1eb7ab

### 结合MediaSession框架与ViewModel实现媒体控制功能 在 Android 开发中,`MediaSession` 是用于处理音频播放和远程控制的核心工具之一。而 `ViewModel` 则是一种生命周期感知型组件,能够存储并管理 UI 相关的数据,从而避免因配置更改而导致数据丢失。 以下是关于如何将 `MediaSession` 和 `ViewModel` 结合使用的具体说明: #### 1. 创建 MediaSession 实例 在 ViewModel 中初始化 `MediaSession` 并绑定回调逻辑。这一步通常会在 ViewModel 的构造函数或者初始化方法中完成。 ```kotlin import android.media.session.MediaSession import androidx.lifecycle.ViewModel class MediaPlayerViewModel(application: Application) : ViewModel() { private val mediaSession: MediaSession by lazy { MediaSession(application, "MediaPlayerService").apply { setCallback(object : MediaSession.Callback() { override fun onPlay() { super.onPlay() // 处理播放事件 } override fun onPause() { super.onPause() // 处理暂停事件 } }) } } init { mediaSession.isActive = true } override fun onCleared() { super.onCleared() mediaSession.release() } } ``` 上述代码展示了如何创建一个简单的 `MediaSession` 实例,并将其封装到 `ViewModel` 中[^5]。 #### 2. 绑定 MediaSession 控制器 为了让 Activity 或 Fragment 能够访问 `MediaSession` 提供的功能,可以通过暴露控制器的方式实现。 ```kotlin val controller: MediaControllerCompat get() = MediaControllerCompat( getApplication(), mediaSession.sessionToken ) ``` 这样可以确保任何需要操作媒体控件的地方都可以安全地获取到对应的控制器实例。 #### 3. 使用 LiveData 更新状态 为了使界面实时反映当前的播放状态变化,在 ViewModel 中引入 `LiveData` 来通知观察者更新界面上的状态信息。 ```kotlin private val _playbackState = MutableLiveData<PlaybackStateCompat>() val playbackState: LiveData<PlaybackStateCompat> = _playbackState fun updatePlaybackState(state: PlaybackStateCompat) { _playbackState.value = state } // 设置初始状态 mediaSession.setPlaybackState(PlaybackStateCompat.Builder().setState( PlaybackStateCompat.STATE_STOPPED, 0L, 1f).build()) updatePlaybackState(mediaSession.controller.playbackState) ``` 这里定义了一个私有的 `_playbackState` 对象作为可变变量,外部只允许读取不可修改版本;每当调用了 `setPlaybackState()` 方法之后都会触发一次新的值广播给订阅该属性的所有监听方[^6]。 #### 4. 配置锁屏卡片显示内容 如果希望用户即使离开应用也能看到正在播放的内容摘要,则还需要额外设置一些元数据参数传递给系统服务层展示出来。 ```kotlin fun setupMetadata(metadataBuilder: MediaMetadataCompat.Builder){ mediaSession.setMetadata(metadataBuilder.build()) } ``` 此部分负责向操作系统报告有关现在正播放歌曲的相关细节比如封面图片链接、艺术家姓名等等[^7]。 --- ### 总结 综上所述,通过以上几个步骤就可以成功地将在 Android 应用程序当中集成起基于 MVVM 架构模式下的多媒体操控能力了。不仅简化了开发流程同时也增强了应用程序稳定性以及用户体验满意度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值