第三方手表如何通过 BLE 控制 iPhone 音乐:理解 Apple Media Service

5 阅读7分钟

在手表上点击暂停,iPhone 上的音乐随即停止;切换下一首,手表上的歌名也跟着更新。这个看似简单的功能,背后涉及两个不同的问题:控制指令如何到达播放器,播放状态又如何回到手表。

谈到蓝牙音乐控制,很多人首先想到 AVRCP。但对于连接 iPhone 的低功耗配件,Apple 还提供了一条值得了解的路径:Apple Media Service,简称 AMS。

AMS 是 Apple 定义并公开文档化的 BLE/GATT 服务,允许外部配件控制 iOS 媒体播放,并获取相关状态。对于以“播放、暂停、切歌、显示当前曲目”为目标的手表,它提供了直接的协议入口。Apple AMS 官方介绍

理解 AMS,首先要明确代码应该运行在哪里。Apple 将提供服务的 iOS 设备称为 Media Source(MS) ,将访问服务的配件称为 Media Remote(MR) 。对应到 GATT,iPhone 是服务端,手表是客户端。

手表固件:AMS Client
        ⇅
    BLE / GATT
        ⇅
iPhone 系统:AMS Server
        ⇅
   当前媒体播放器

因此,手表固件需要发现并访问 iPhone 提供的 AMS 服务。如果反过来,在手表上创建同名服务,再等待 iPhone 向它写入播放状态,交互方向就错了。

GATT 客户端也不意味着手表必须主动扫描并连接手机。蓝牙连接角色与 GATT 访问角色属于不同层次。Nordic 的官方示例就叫作 Peripheral AMS client:设备可以承担 Peripheral 连接角色,同时访问对端的 AMS 服务。Nordic 官方实现示例

这条路径也解释了配套 App 的职责边界。AMS 控制指令由配件直接交给 iOS 系统,不要求配套 App 逐条转发。  配套 App 仍可能负责发现、配置、建立连接和其他业务,但这些工作应与媒体控制通道分开设计。

对于音乐 App,公开的 MPRemoteCommandCenter 用于接收来自系统控件和外部配件的控制事件。它与 AMS 处于不同层面,也不等于给配套 App 提供了任意控制其他播放器的权限。Apple MPRemoteCommandCenter 文档

AMS 的协议结构比较紧凑。其服务 UUID 为:

89D3502B-0F36-433A-8EF4-C502AD55F8DC

主要交互通过三个特征完成:

特征职责
Remote Command发送播放控制命令,接收当前支持的命令列表
Entity Update注册关注的属性,接收属性变化通知
Entity Attribute读取在通知中被截断的完整属性值

可以将其理解为三个入口:发指令、收更新、补读长内容。实际接入时,应发现并检查可用特征,而不是假定所有特征必然存在。Apple AMS 服务规范

控制命令采用单字节 ID。例如,播放是 0x00,暂停是 0x01,播放/暂停切换是 0x02,下一首和上一首分别是 0x03、0x04。协议还定义了音量增减、随机与循环模式切换等操作。

命令是否可用,需要以当前播放器报告的能力为准。  手表界面不应因为协议定义了某个命令,就始终显示对应按钮。

媒体信息则分为三个实体:

实体提供的信息
Player播放器名称、播放状态、播放速度、已播放时间、音量
Queue当前队列位置、曲目数量、随机和循环模式
Track歌手、专辑、歌名、总时长

这里有一个容易误解的地方:Queue 提供的是队列属性,不是完整的播放列表内容。知道当前播放第几首、队列共有多少首,并不代表能读取每首歌的名称并任意点播。Apple 命令与属性定义

以显示当前曲目为例,配件建立连接并完成所需的安全建立流程后,发现 AMS、订阅通知,再声明需要哪些属性。订阅歌手、专辑、歌名和时长时,向 Entity Update 写入:

02 00 01 02 03
│  │  │  │  └─ 时长
│  │  │  └──── 歌名
│  │  └─────── 专辑
│  └────────── 歌手
└───────────── Track 实体

订阅播放器名称、播放信息和音量,则写入:

00 00 01 02

Nordic 的示例展示了这些字节序列,以及通过开发板按钮触发播放、暂停和切歌的验证流程。它可以作为理解“固件操作如何映射到 AMS 交互”的参考。Nordic 示例:初始化与属性订阅

长歌名还需要额外处理。属性通知包含实体、属性、标志和文本值;当文本被标记为截断时,配件应通过 Entity Attribute 选择目标属性,再读取完整内容。只处理普通通知,可能让较长的歌名或专辑名显示不完整。Apple 属性更新与读取流程

播放进度也不需要每秒向手机查询。AMS 的播放信息包含播放速度和已播放时间,手表可以根据接收后的本地时间推算进度,再用后续状态更新校正。

例如,属性值 1,1.0,42.5 表示正在播放、正常速度、发送时已播放 42.5 秒。若接收后经过约 3 秒,界面可以估算进度为约 45.5 秒。这种方式适合低功耗设备,但能够显示进度,不代表协议提供了拖动到任意时间点的控制命令。Apple 播放信息与进度计算说明

从原型走向产品,真正需要投入精力的是状态一致性。Apple 明确指出:命令写入成功,只代表命令已经转交播放器,不保证播放器执行了动作。  AMS 本身也不保证始终存在,配件应关注 GATT 的 Service Changed,处理服务发布和撤销。Apple 服务生命周期与命令语义

基于这些约束,实现时可以采用以下策略:

  • 区分“已发送”和“已生效”。  用户点击后可以显示短暂反馈,最终播放状态仍由回报校正。
  • 谨慎重试切换类命令。  播放/暂停切换若被执行两次,可能回到原来的状态;超时不能简单等同于执行失败。
  • 重连后重新确认状态。  检查服务、特征、能力与订阅,避免继续显示断线前的旧曲目。
  • 串行执行长属性读取。  将“选择属性—读取属性”作为完整操作调度,防止并发请求相互覆盖目标。

测试也应覆盖用户真实会遇到的变化:锁屏、暂停、拖动进度、切换播放器、长中文歌名、手机与手表短暂失联。若日志分别记录用户操作、GATT 写入结果和后续状态回报,就更容易判断问题发生在连接、协议还是播放器响应阶段。

AMS 的适用范围也需要在产品设计时明确。公开接口没有定义封面传输、完整媒体库浏览、按曲目 ID 任意选歌、指定控制某个 App,以及设置任意播放时间或绝对音量的操作。若产品需要这些能力,应单独寻找适用接口并验证,而不能从基础遥控能力推导出来。Apple AMS 接口全集

Apple 的 AMS 文档目前位于 Documentation Archive,页面标注的更新时间为 2014 年 9 月 17 日。接入时应以公开规范为起点,并在明确的 iPhone、iOS 和播放器版本组合上验证。协议存在、固件实现正确与目标产品体验稳定,是需要分别确认的三件事。

对于一块主要承担手机音乐遥控的 BLE 手表,合理的第一步是跑通一条最小链路:发现 AMS、订阅歌名与播放状态、发送播放/暂停命令,再验证断线恢复。  当这条链路可靠后,再逐步增加进度显示、音量控制和播放器能力适配,技术范围和验收标准都会更清晰。