很多人用蓝牙连车机时,会发现手机里的音乐APP、FM收音机、视频播放器都能被车机识别并切换控制,这背后就是AVRCP的多媒体播放器管理机制。它解决的核心问题,就是让控制端(车机、耳机)能精准识别并切换媒体源(手机)上的多个音频应用,实现跨应用的播放控制。本文就深度拆解多播放器的发现-选择-变更通知完整流程,把规范里的信令交互变成开发能直接落地的逻辑,吃透多播放器场景的每一步设计要点。
目录
[2.1 阶段一:多播放器发现与选择](#2.1 阶段一:多播放器发现与选择)
[2.2 阶段二:播放器变更通知机制](#2.2 阶段二:播放器变更通知机制)
[3.1 核心指令PDU构造](#3.1 核心指令PDU构造)
[3.2 开发避坑点](#3.2 开发避坑点)
一、多播放器场景整体流程概览
多播放器的交互分为两大核心阶段:
发现与选择阶段:控制端主动拉取媒体源上所有可用播放器列表,用户选择后建立控制绑定
变更通知阶段:注册播放器切换事件,实现跨应用切换时的状态同步
整个流程围绕控制端(CT)和目标端(TG)的两次关键交互展开,规范里明确了每一步的指令、响应和状态流转,没有冗余设计,是车载蓝牙、多设备音频同步的核心能力
二、流程逐环节精讲
2.1 阶段一:多播放器发现与选择
这一阶段的目标是让控制端知道媒体源上有哪些播放器可选,并完成控制对象的绑定。

1. 指令 :GetFolderItems_Cmd(Media Player List)
这是发现播放器的核心指令,控制端通过它向媒体源发起查询,请求获取所有可用的媒体播放器列表。
交互详解
指令作用:拉取媒体源上所有注册的音频播放器,包括音乐APP、FM收音机、视频播放器等
响应数据:返回的列表包含播放器ID、名称、类型等关键信息,控制端可以直接展示给用户选择
场景类比:就像车机打开蓝牙音频列表,手机上的QQ音乐、网易云、FM电台都显示出来,用户点选哪个就控制哪个
2. 指令 :SetAddressedPlayer(Player ID)
用户选择播放器后,控制端会发送这个指令,告诉媒体源我现在要控制这个播放器
交互详解
核心作用:建立控制绑定,后续所有播放、暂停、音量调节指令都会发送到这个指定的播放器
响应逻辑:媒体源收到指令后,返回成功响应,并将当前控制对象切换为目标播放器
关键要点:一次只能绑定一个播放器,切换时需要重新发送该指令
2.2 阶段二:播放器变更通知机制
这一阶段解决的是媒体源侧主动切换播放器时,控制端如何同步状态的问题,避免车机/耳机停留在旧播放器的控制状态。

1. 指令 :RegisterNotification(ADDRESSED_PLAYER_CHANGED)
控制端在绑定播放器后,会立即注册播放器变更事件。
交互详解
事件ID:ADDRESSED_PLAYER_CHANGED,对应规范定义的通知事件
初始响应:媒体源会返回当前绑定的播放器ID,让控制端确认初始状态
核心作用:当媒体源侧(比如手机)手动切换播放器时,控制端能收到通知并更新控制对象
2. 指令 :ChangedResponse(ADDRESSED_PLAYER_CHANGED, PlayerID)
当媒体源侧的绑定播放器发生变化时,会主动发送这个通知给控制端。
交互详解
触发场景:用户在手机上从QQ音乐切换到FM收音机,媒体源主动推送变更通知
控制端动作:收到通知后,会更新本地的控制对象,并重新注册变更事件,等待下一次切换
关键要点:变更通知必须携带新的播放器ID,控制端需要验证ID的有效性
三、开发关键要点与代码示例
3.1 核心 指令 PDU 构造
(1)播放器列表查询 指令
cpp
// GetFolderItems_Cmd 核心字段
uint8_t avrcp_get_folder_items[] = {
0x01, // Ctype: CONTROL
0x90, // Subunit: Panel
0x00, // Opcode: VENDOR DEPENDENT
0x00, 0x19, 0x58, // SIG公司ID
0x71, // PDU ID: GetFolderItems
0x00, // 包类型
0x00, 0x08, // 参数长度
0x00, 0x00, 0x00, 0x00, // UID(根目录)
0x01, // 媒体播放器类型
0x00, 0x00 // 起始索引
};
(2)绑定播放器 指令
cpp
// SetAddressedPlayer 核心字段
uint8_t avrcp_set_addressed_player[] = {
0x01, // Ctype: CONTROL
0x90, // Subunit: Panel
0x00, // Opcode: VENDOR DEPENDENT
0x00, 0x19, 0x58, // SIG公司ID
0x60, // PDU ID: SetAddressedPlayer
0x00, // 包类型
0x00, 0x02, // 参数长度
0x00, 0x01 // 目标播放器ID
};
3.2 开发避坑点
-
播放器列表查询必须包含类型过滤,避免返回非音频类媒体对象
-
绑定播放器后,必须立即注册变更事件,否则媒体源侧切换时控制端无法感知
-
播放器ID必须全局唯一,跨应用切换时不能出现ID冲突
-
初始InterimResponse必须携带有效播放器ID,避免控制端显示异常
四、测验
**题目:**AVRCP多播放器场景中,GetFolderItems指令的作用是什么?响应数据需要包含哪些关键信息?(2024年车载蓝牙工程师校招真题)
答案
GetFolderItems指令用于控制端向媒体源查询所有可用的媒体播放器列表。响应数据需要包含播放器ID、名称、类型等关键信息,控制端可据此展示给用户选择。
**题目:**SetAddressedPlayer指令发送后,媒体源的核心动作是什么?控制端后续需要做什么?
答案
媒体源会切换当前控制对象为指定播放器,并返回成功响应。控制端需要立即注册ADDRESSED_PLAYER_CHANGED事件,监听后续播放器变更。
**题目:**ADDRESSED_PLAYER_CHANGED事件的触发场景有哪些?控制端收到通知后需要执行什么操作?
答案
触发场景包括媒体源侧用户手动切换播放器、应用被后台杀死、新播放器启动等。控制端收到通知后,需要更新控制对象并重新注册该事件。