本节将解释如何将媒体播放器应用程序分离为媒体控制器 (用于 UI) 和媒体会话(用于实际播放器). 它描述了两种媒体应用程序架构: 一种客户端 / 服务器设计, 适用于音频应用程序, 另一种是视频播放器的单活动设计. 它还展示了如何使媒体应用程序响应硬件控制并与使用音频输出流的其他应用程序合作.
播放器和用户界面
播放音频或视频的多媒体应用程序通常有两部分:
一种将数字媒体带入并将其呈现为视频和 / 或音频的播放器
一个带有传输控件的 UI, 可以运行播放器并显示播放器的状态
在 Android 中, 你可以从头开始构建自己的播放器, 或者你可以从以下选项中选择:
MediaPlayer 类为支持最常见的音频 / 视频格式和数据源的基本播放器提供了基本功能.
ExoPlayer 是一个开源库, 可以公开底层的 Android 音频 API.ExoPlayer 支持诸如 Dash 和 HLS 流等在 MediaPlayer 中不可用的高性能特性. 您可以自定义 ExoPlayer 代码, 使添加新组件变得容易. ExoPlayer 只能在 Android 4.1 及更高版本下使用.
媒体会话 media session 和媒体控制器 media controller
虽然 UI 和播放器的 API 可以是任意的, 但是对于所有媒体播放器应用程序来说, 这两部分之间的交互本质上是相同的. Android 框架定义了两个类, 一个媒体会话和一个媒体控制器, 它们为构建媒体播放器应用程序强加了定义良好的结构.
媒体会话和媒体控制器使用与标准播放器动作 (播放, 暂停, 停止等) 对应的预定义回调进行通信, 以及可扩展的定制调用, 您可以使用这些调用定义应用程序特有的特殊行为.
媒体会话 media session
媒体会话负责与播放器的所有交流. 它会将播放器的 API 隐藏到应用程序的其他部分. 播放器只能从控制它的媒体会话中调用.
该会话维护播放器状态 (播放 / 暂停) 和关于正在播放内容的信息的表示. 会话可以从一个或多个媒体控制器接收回调. 这使得你的播放器能够被你的应用程序的 UI 以及运行 Wear OS 和 Android Auto 的配套设备所控制.
媒体控制器 media controller
媒体控制器隔离你的 UI. 你的 UI 代码只与媒体控制器通信, 而不是播放器本身. 媒体控制器将传输控制操作转换为对媒体会话的回调. 当会话状态发生变化时, 它还从媒体会话接收回调. 这提供了一种自动更新关联 UI 的机制. 媒体控制器一次只能连接到一个媒体会话.
当您使用媒体控制器和媒体会话时, 您可以在运行时部署不同的接口和 / 或播放器. 你可以改变你的应用的外观和 / 或性能独立取决于设备运行的能力.
视频应用和音频应用
当播放视频时, 你的眼睛和耳朵都在工作. 播放音频时, 你是在听, 但你也可以同时使用不同的应用程序. 每个用例都有不同的设计.
视频应用
视频应用程序需要一个窗口来查看内容. 由于这个原因, 视频应用程序通常被实现为一个单一的 Android 活动. 视频显示的屏幕是活动的一部分.
音频应用程序
音频播放器并不总是需要其 UI 可见. 一旦开始播放音频, 播放器就可以作为后台任务运行. 用户可以切换到另一个应用程序, 一边听一边工作.
要在 Android 中实现这个设计, 您可以使用两个组件构建一个音频应用程序: 一个用于 UI 的活动, 一个用于播放器的服务. 如果用户切换到另一个应用程序, 服务可以在后台运行. 通过将音频应用程序的两个部分分解成单独的组件, 每个组件都可以更高效地独立运行. 与没有 UI 的播放器相比, UI 通常是很短暂的, 因为播放器在没有 UI 的情况下可能会运行很长时间.
支持库提供了两个类来实现这种客户机 / 服务器方法: MediaBrowserService 和 MediaBrowser. 服务组件作为包含媒体会话及其播放器的 MediaBrowserService 的子类实现. 带有 UI 和媒体控制器的活动应该包括一个 MediaBrowser, 它与 MediaBrowserService 通信.
使用 MediaBrowserService 可以让配套设备 (如 Android Auto 和 Wear) 很容易地发现你的应用程序, 连接到它, 浏览内容和控制回放, 而不需要访问你的 UI 活动.
媒体应用和 Android 音频基础设施
一个设计良好的媒体应用程序应该和其他播放音频的应用程序 "一起玩得很好". 它应该准备好与使用音频的设备上的其他应用程序共享手机和合作. 它还应该对设备上的硬件控件做出响应.
上述行为查看 Controlling Audio Output.
media-compat 库
media-compat 库包含的类有助于构建播放音频和视频的应用程序. 这些类与运行 Android 2.3 (API level 9)及更高版本的设备兼容. 他们还与其他 Android 特性一起工作, 以创建一个舒适的, 熟悉的 Android 体验.
媒体会话和媒体控制器的推荐实现是和类, 它们在 media-compat 支持库中定义. 它们替换了 Android 5.0 (API 级别 21)中引入的类 MediaSession 和 MediaController 的早期版本. compat 类提供了相同的功能, 但使开发应用程序更容易, 因为只需要编写一个 API. 库通过将媒体会话方法转换为旧平台版本上的等效方法来处理向后兼容性.
如果您已经有了一个使用旧类的工作应用程序, 我们建议更新到 compat 类. 使用 compat 版本时, 可以删除对 registerMediaButtonReceiver()和的任何方法的所有调用.
测量性能
在 Android 8.0 (API 级别 26)和更高版本中, 有些媒体类可以使用 getMetrics()方法. 它返回一个包含配置和性能信息的对象, 表示为属性和值的映射. getMetrics()方法用于这些媒体类:
- MediaPlayer.getMetrics()
- MediaRecorder.getMetrics()
- MediaCodec.getMetrics()
- MediaExtractor.getMetrics()
为每个实例分别收集指标, 并为实例的生命周期持久保存. 如果没有可用的指标, 该方法返回 null. 返回的实际指标取决于类.
来源: https://juejin.im/post/5bbdc1a9e51d450e877f9734