媒体应用架构概述

本节介绍如何将媒体播放器应用分离成媒体控制器(用于 UI)和媒体会话(用于实际的播放器)。它描述了两种媒体应用架构:适用于音频应用的客户端/服务器设计,以及适用于视频播放器的单活动设计。它还展示了如何使媒体应用响应硬件控制并与使用音频输出流的其他应用协作。

播放器和 UI

播放音频或视频的多媒体应用通常包含两个部分

  • 一个播放器,它接收数字媒体并将其渲染为视频和/或音频
  • 一个带传输控制的 UI,用于运行播放器,并可选地显示播放器的状态

ui-and-player

在 Android 中,您可以从头开始构建自己的播放器,也可以选择以下选项

  • MediaPlayer 类提供了基本功能,用于构建支持最常见音频/视频格式和数据源的简易播放器。
  • ExoPlayer 是一个基于更低级别媒体框架组件(如 MediaCodecAudioTrack)构建的开源库。ExoPlayer 支持 DASH 等高性能功能,这些功能在 MediaPlayer 中不可用。您可以自定义 ExoPlayer 代码,从而轻松添加新组件。ExoPlayer 只能与 Android 4.1 及更高版本一起使用。

媒体会话和媒体控制器

虽然 UI 和播放器的 API 可以是任意的,但两者之间交互的本质对于所有媒体播放器应用程序来说基本相同。Android 框架定义了两个类,即 *媒体会话* 和 *媒体控制器*,它们为构建媒体播放器应用程序定义了明确的结构。

媒体会话和媒体控制器使用预定义的回调相互通信,这些回调对应于标准播放器操作(播放、暂停、停止等),以及可扩展的自定义调用,您可以使用这些调用来定义应用程序特有的特殊行为。

controller-and-session

媒体会话

媒体会话负责与播放器的所有通信。它将播放器的 API 隐藏在应用程序的其余部分之外。播放器只能从控制它的媒体会话中调用。

会话维护播放器状态(播放/暂停)和正在播放内容信息的表示。会话可以从一个或多个媒体控制器接收 回调。这使得您的播放器可以由应用程序的 UI 以及运行 Wear OS 和 Android Auto 的配套设备控制。响应回调的逻辑必须一致。对 MediaSession 回调的响应应该与启动回调的客户端应用程序无关。

媒体控制器

媒体控制器隔离您的 UI。您的 UI 代码仅与媒体控制器通信,而不是播放器本身。媒体控制器将传输控制操作转换为对媒体会话的回调。它还在会话状态发生变化时从媒体会话接收回调。这提供了一种机制来自动更新关联的 UI。媒体控制器一次只能连接到一个媒体会话。

当您使用媒体控制器和媒体会话时,您可以在运行时部署不同的界面和/或播放器。您可以根据运行应用程序的设备的功能独立更改应用程序的外观和/或性能。

视频应用程序与音频应用程序

在播放视频时,您的眼睛和耳朵都参与其中。在播放音频时,您正在听,但您也可以同时使用其他应用程序。每个用例都有不同的设计。

视频应用程序

视频应用程序需要一个窗口来查看内容。因此,视频应用程序通常实现为单个 Android 活动。视频出现的屏幕是活动的一部分。

video player activity

音频应用程序

音频播放器并不总是需要其 UI 可见。一旦开始播放音频,播放器就可以作为后台任务运行。用户可以切换到另一个应用程序,并在继续收听的同时工作。

要在 Android 中实现此设计,您可以使用两个组件构建音频应用程序:用于 UI 的活动和用于播放器的服务。如果用户切换到另一个应用程序,服务可以在后台运行。通过将音频应用程序的两个部分分解为单独的组件,每个组件可以在其自身上更有效地运行。与播放器相比,UI 通常是短暂的,播放器可能在没有 UI 的情况下运行很长时间。

Audio activity and BrowserService

支持库提供两个类来实现此客户端/服务器方法: MediaBrowserServiceMediaBrowser。服务组件实现为 MediaBrowserService 的子类,其中包含媒体会话及其播放器。具有 UI 和媒体控制器的活动应包含一个 MediaBrowser,它与 MediaBrowserService 通信。

使用 MediaBrowserService 使得配套设备(如 Android Auto 和 Wear)可以轻松发现您的应用程序,连接到它,浏览内容并控制播放,而无需完全访问应用程序的 UI 活动。实际上,可以有多个应用程序同时连接到同一个 MediaBrowserService,每个应用程序都有自己的 MediaController。提供 MediaBrowserService 的应用程序应该能够处理多个同时连接。

媒体应用程序和 Android 音频基础架构

设计良好的媒体应用程序应与其他播放音频的应用程序“协同工作”。它应该准备好共享手机,并与设备上使用音频的其他应用程序协作。它还应该响应设备上的硬件控制。

plays-with-others

所有这些行为都在 控制音频输出 中描述。

媒体兼容库

媒体兼容 库包含有助于构建播放音频和视频的应用程序的类。这些类与运行 Android 2.3(API 级别 9)及更高版本的设备兼容。它们还与其他 Android 功能一起使用,以创建舒适、熟悉的 Android 体验。

媒体会话和媒体控制器的推荐实现是类 MediaSessionCompatMediaControllerCompat,它们在 媒体兼容支持库 中定义。它们取代了 Android 5.0(API 级别 21)中引入的类 MediaSessionMediaController 的早期版本。兼容类提供相同的功能,但使开发应用程序变得更容易,因为您只需要编写一个 API。该库通过在可用时将媒体会话方法转换为旧平台版本上的等效方法,来处理向后兼容性。

如果您已经有一个使用旧类的应用程序,我们建议您更新到兼容类。当您使用兼容版本时,您可以删除对 registerMediaButtonEventReceiver()RemoteControlClient 中的任何方法的所有调用。

衡量性能

在 Android 8.0(API 级别 26)及更高版本中, getMetrics() 方法可用于某些媒体类。它返回一个 PersistableBundle 对象,其中包含配置和性能信息,表示为属性和值的映射。 getMetrics() 方法为以下媒体类定义

为每个实例单独收集指标,并在实例的生命周期内持续存在。如果指标不可用,则该方法返回 null。返回的实际指标取决于类。