机器翻译结果,仅用于学习,不喜勿喷,原文档链接。
在设置单播和广播流的复杂性之后,涵盖电话和媒体控制的四个spec令人耳目一新,尽管内容很全面。当蓝牙技术刚被开发出来时,我们的大多数移动产品都相当简单,只做一件事。移动电话使用蜂窝网络拨打电话,音乐播放器根据它们支持的任何物理媒体播放音乐——通常是预先录制的磁带或 CD。从那时起,电话和媒体(我们指的是音乐和我们可以停止和启动的任何其他音频)都变得更加复杂。
对于电话,我们不再将手机限制在蜂窝网络上。向 IP 语音 (VoIP) 的转变见证了基于互联网的电话服务的爆炸式增长,无论是作为我们手机上的“Over the Top” (OTT) 应用程序,还是作为我们笔记本电脑和 PC 上的程序。大流行和在家工作的相关增长加速了它们的使用。虽然我们仍然拨打蜂窝电话,但我们也使用 Skype、Zoom、Teams 和越来越多的其他电话服务,有时同时使用多个。
媒体也发生了变化。正如我们在第 1 章中看到的,蓝牙音频的增长与音乐流媒体服务的增长并行。我们不再拥有我们所听的大部分内容,而是按需借用。这意味着停止、播放、快进和快退等传统控件需要补充新的控件,这些控件超出了物理设备的范围,到达了音频源。
蓝牙经典音频profile的控制机制一直在努力跟上这种发展,特别是在电话领域,它们仍然基于旧的“AT”命令集,该命令集最初是在 1981 年为固定电话调制解调器设计的,然后被集成到1990 年代早期的 GSM 标准和 2000 年代早期蓝牙技术的耳机和Hands-Free profile。LE audio 的发展使我们有机会回到电话和媒体控制的第一原则,通用状态机同样适用于蜂窝和 VoIP 电话,以及各种本地和远程媒体源。
当前使用两组profile和服务定义内容控制。在电话的情况下,它们是:
- TBS – 电话承载服务,它定义处理呼叫的设备的状态,以及
- CCP – 呼叫控制profile,它是在 TBS 上操作的client。
对于媒体,相应的一对spec是:
- MCS – 媒体控制服务,定义媒体源的状态,以及
- MCP – 媒体控制profile,它是作用于 MCP 的client。
9.1 术语和通用 TBS 和 MCS 特性
到目前为止,我主要使用 CAP 中的 Initiator 和 Acceptor 术语作为描述音频流发生情况的最简单方法。现在我们正在研究与音频流正交的控制,这不再合适。由于LE audio 的基本架构将音频数据平面和控制平面分开,这意味着可以在不参与音频流的设备上实现控制功能。因此,我们需要在本章中恢复到client-server术语,其中server是服务的实例——定义媒体播放器或电话的状态。对于电话承载和媒体控制服务,server位于发起方。 Client 可以在 Acceptor 上,但同样可能在远程遥控上,因为它更易于使用,特别是对于耳塞和助听器等小型设备。我们已经习惯了远程遥控的易用性——这就是它们被发明的原因。它不需要看起来像传统的远程遥控——它可以是智能手表、其他可穿戴设备,甚至是电池盒上的按钮。此外,可以有多个client同时在server上运行。您可以在耳塞上接听电话,但用手表将其终止。
正如我们将看到的,控制profile可以让我们在 Initiator 上移动媒体和呼叫状态,反映用户希望开始或接听电话,或播放或暂停一段音乐。他们不做的是启动或停止与这些决定相关的任何音频流。控制命令与传输音频数据的音频流的配置和建立之间的链接完全取决于实现。由initiator上的应用程序根据需要将它们绑定在一起。
在 TBS 和 MCS 中,服务spec包括单独的 TBS 和 MCS 实例,可以为设备上的每个应用程序实例化。例如,如果您的手机支持 Skype、WhatsApp 和 Zoom 以及蜂窝电话,它可以为每个应用程序包含一个单独的 TBS 实例。如果它是一个媒体播放设备,它可以包含一个用于 Spotify、BBC Sounds 和 Netflix 的 MCS 实例。
但是,如果您通过一对耳塞控制电话或音乐,并且用户界面非常有限,那么您不太可能想要,甚至无法区分不同的应用程序。为了解决这个问题,TBS 和 MCS spec各自包含一个通用版本的服务,分别称为通用电话承载服务 (GTBS) 和通用媒体控制服务 (GMCS)。它们的行为方式与 TBS 和 MCS 完全相同,但为server设备提供了单一接口。将来自client的传入命令映射到适当的应用程序取决于实现。
图 9.1 是其工作原理的简单表示。每个内容控制server都必须包含通用服务的单个实例——GTBS 或 GMCS,如果它想将控制直接暴露给应用程序,则可能具有单独的 TBS 和 MCS 实例。您可以拥有与电话和媒体应用程序一样多的每个服务的实例,该映射取决于实现。
各自的profile——CCP 和 MCP,定义了client和server角色,如图 9.2 所示。
实现可以使用这些服务的组合来:
- 将每个应用程序视为独特的媒体播放器或电话服务,
- 将设备视为单个电话或媒体播放器,其中命令作用于整个设备,或
- 一种组合,其中命令的子集可以针对特定应用程序,根据其特定的内容控制 ID (CCID) 进行映射。
在所有情况下,映射都取决于产品实施。
TBS 和 MCS 都包含广泛的功能,我们将在下面介绍。很多时候,低功耗蓝牙音频关注的是耳塞,因为这是迄今为止最大的市场。耳塞有限的用户界面 (UI) 可能会让读者想知道为什么包含这么多这些功能,以及为什么强制要求的功能如此之少。这忽略了蓝牙音频的历史,直到最近,主要的音频应用都在车载套件中,其中提供了非常丰富的控制和信息接口。 TBS 和 MCS 都旨在复制车载套件中当前可用的许多功能,以便LE audio 可用于构建这些产品的下一代,以及扩展它们以添加新功能,特别是在媒体控制方面玩家。
9.2 控制拓扑
两对控制spec的核心是状态的概念,在服务spec中定义。状态保存在音频来源的设备上——MCS 的媒体播放器或电话设备,充当 TBS 的呼叫承载的网关,但始终是Initiator 。client设备可以实现相应的profile,该profile写入server上的控制点,导致其状态转换。一旦进行了转换(也可能通过用户按下按钮或触摸屏幕在本地发生),server会通知其新状态。这与我们在 ASCS 状态机中遇到的原理完全相同——一个设备拥有状态,多个client可以读取和操作它。在MCP和CCP的情况下,client可以是接收音频流的设备,也可以是包含Commander角色的设备,例如远程遥控或智能手表。但是,在这种情况下,Commander 中的client将在 Initiator 上运行,而不是在 Acceptor 上运行,如图 9.3 所示。
除了控制点和状态特征之外,每个服务还包含大量可供选择的特征,这些特征可以被读取或通知以确定有关应用程序和提供它的外部服务的更多信息。
9.3 TBS 和 CCP
电话控制spec的核心是通用呼叫状态机,如图 9.4 所示。
状态机的核心是 Active 状态,它表示呼叫的存在。在大多数情况下,当Initiator 和Acceptor之间建立了单播音频流时,就会达到这种状态,通常由双向流组成。但是,如果使用有线耳机接听电话,或者如果电话被用作没有活动音频流的Hands-Free 电话,则状态机同样有效。这强调了控制平面(在本例中为 TBS / CCP 关系)和音频数据平面(即 BAP / ASCS 关系)之间的区别。应用程序可以根据需要将它们绑定在一起。 (虽然它们是 GAF 不可或缺的一部分,但它们并不限于LE audio ,还可以与其他应用程序一起使用。)
状态机周围的转换可以由外部event提示,例如:
- 来电,
- 一个 CCP client写入 TBS 呼叫状态特征,
- 本地用户操作,例如接听电话,或
- 远程调用者的操作。
图 9.4 中的远程操作(远程警报启动、远程应答、远程保持和远程检索在每个命令的末尾用星号 (*) 标记)。这些转换只能由远程调用者进行。状态由呼叫状态特征公开,只要呼叫状态发生变化,就会通知client。
9.3.1 呼叫状态特性
呼叫状态特征是设备上所有当前呼叫的数组。一旦任何呼叫进入非空闲状态,TBS 就会为其分配一个唯一的、单八位组的顺序索引号,称为 Call_Index,其值介于 1 和 255 之间,在呼叫状态特性中通知。 (TBS 的呼叫控制状态机不包含空闲状态,但为了清楚起见,在图 9.4 中显示了一个)。呼叫状态特征的第二个八位字节标识每个呼叫的当前状态,最后一个八位字节保存与该呼叫相关的呼叫标志。
呼叫状态特征的格式如图 9.5 所示。
表 9.1 列出了呼叫状态特性中返回的状态值。
State | Name | Description |
---|---|---|
0x00 | Incoming | 来电(通常会产生铃声)。 |
0x01 | Dialing | 已拨出电话,但尚未通知对方(传统拨号音状态)。 |
0x02 | Alerting | 正在提醒对方(他们有铃声)。 |
0x03 | Active | 呼叫建立时有活动对话。 |
0x04 | Locally Held | 呼叫已连接,但在本地保持(见下文) |
0x05 | Remotely Held | 呼叫已连接,但远程保持(见下文) |
0x06 | Locally and Remotely Held | 呼叫已连接,但在本地和远程都保持(见下文) |
0x07-0xFF | RFU | 保留供将来使用 |
9.3.1.1 本地和远程保持
状态 0x04、0x05 和 0x06 指的是已被保持的呼叫。这些状态的区别在于是谁将呼叫置于保持状态。 0x04 值表示它已被本地搁置,即由具有此TBS 实例的电话或PC 的用户搁置。 0x05 表示已被对方搁置,0x06 表示通话双方均已搁置。
可以通过写入控制点来检索本地保持的呼叫(带回活动状态)。远程保持的呼叫需要由远程方检索。可以应用于远程保持呼叫的唯一本地操作是终止它。
9.3.1.2 Call Flags
呼叫状态特性的最后一个八位字节是一个包含呼叫信息的位域,其含义和对应的值如表 9.2 所示。
Bit | Description | Value |
---|---|---|
0 | 呼叫方向 | 0 = 来电 1 = 拨出电话 |
1 | server保留信息 | 0 = 未保留 1 = 保留 |
2 | 网络保留信息 | 0 = 由网络提供 1 = 网络保留 |
3 - 7 | RFU | 保留供将来使用 |
第 1 位和第 2 位指示信息,例如 URI(通常是呼叫者 ID)或友好名称,可能由于本地或网络策略而被故意保留。可以设置其中一个或两个,在这种情况下,关联特征的字段可以为空或 null。或者,server可以用适当的文本填充它们,例如“保留”或“未知呼叫者”。策略和文本的选择是特定于实现的。
9.3.1.3 UCI 和 URI
您将在电话应用程序中遇到的两个首字母缩写词是 URI 和 UCI,它们代表统一资源标识符和统一呼叫者标识符。两者都旨在提供涵盖各种电话应用程序和载体的呼叫信息。
统一呼叫者标识符本质上是承载者;例如,“Skype”或“wtsap”。 UCI 的值列在蓝牙统一呼叫者标识符分配号码文档中,通常缩写为不超过五个字符。因此 WhatsApp 是“wtsap”。标准电话号码使用“E.164”或“tel:”的 UCI,表示标准拨号器格式。
统一资源标识符是 UCI 和呼叫者 ID 的组合,即呼叫者的号码或用户名,具体取决于应用程序。它可以用于来电,其中它是来电显示,或去电。应用程序可以使用 URI 的 UCI 部分进行拨出呼叫,以选择适当的电话应用程序进行呼叫。 URI 表示为 UTF-8 字符串。
9.3.2 TBS呼叫控制点特性
正如我们在 BAP 和 ASCS 中看到的,client可以通过写入控制点特征来围绕其状态机移动server。在这种情况下,它是 TBS 呼叫控制点特性。这需要一个操作码,后跟一个取决于特定操作码的参数,如图 9.6 所示。
表 9.3 显示了当前的操作码并描述了它们的用途。
Opcode | Name | Parameter | Description |
---|---|---|---|
0x00 | Accept | Call_Index | Accepts the incoming call. |
0x01 | Terminate | Call_Index | Terminate the call associated with Call_Index, regardless of its state. |
0x02 | Local Hold | Call_Index | Places an Active or Incoming call with Call_Index on Local Hold |
0x03 | Local Retrieve | Call_Index | Moves a locally held call to the Active state. |
0x04 | Originate | URI | Starts a call to the URI. |
0x05 | Join | List of Call_index values | Joins the calls identified in the list of Call_Index values. |
0x06 – 0xFF | RFU | Reserved for Future Use |
表 9.3 的操作码是对server的请求,它传递给相关的电话应用程序。其中一些:Accept、Terminate 和 Originate,指的是电话应用程序将在本地执行的操作。 Local Hold and Retrieve一般需要传回网络,Join几乎都是网络函数。根据特定的电话承载和应用程序,并非所有这些功能都可用。根据当前的电话资源和网络连接,它们也可能会失败。例如,如果当前呼叫处于活动状态,则某些电话服务不允许拨打呼叫。同样,如果没有蜂窝信号,发起呼叫的尝试将失败。
TBS 实例可以通过使用呼叫控制可选操作码特性来指示是否支持本地保持和加入功能。这是呼叫控制client可以读取以确定它是否应该发出这些命令的位字段。此字段中的值通常至少在会话期间是静态的,并且通常在设备的生命周期内。如果操作成功,则通知 Call State 特性,通知 Client 当前的 State 和 Call_Index。在操作码是 Originate (0x04) 的情况下,这是第一次让client知道 Call_Index。
当client写入 TBS 调用控制点特性失败时,调用控制点特性使用以下格式通知操作码写入的结果:
Result_Code 指示成功,或提供操作失败的原因。这些代码列在 TBS spec的表 3.11 中。
9.3.3 来电、带内和带外铃声
在传统的电话设计中,用户知道来电的第一件事就是电话响铃。一旦您引入蓝牙连接,这就会变得更加复杂。电话仍然可以听到铃声,或者铃声可能发生在您的耳塞中(如果您戴着它们)。或者两者都可能发生。
还有一个更复杂的问题。您在耳塞中听到的铃声可能与您手机上的声音相同,也可能是耳塞产生的本地生成的铃声,这会有所不同。如果它与手机的声音相同,则需要存在来自手机的音频流,该音频流携带与手机扬声器上播放的相同铃声音频。这称为带内铃声。带内铃声的问题是您需要设置音频流来承载它,这可能意味着将现有的音频流拆除到另一台设备。想象一下您使用耳塞收听电视并且手机响铃的用例。对于带内铃声,您的耳塞可能需要终止与电视的音频流,并将其替换为手机中的音频流。如果接听电话,那不是问题,但如果您拒绝接听电话,则需要重新连接到电视,这样的用户体验很差。
另一种方法是让手机将其来电特性通知您的耳塞。这包含 Call_Index 和 URI,即 URI 方案和来电的呼叫者 ID。您耳塞中的呼叫控制client可以生成本地铃声,提醒您有来电。如果您接受呼叫,呼叫控制client会将接受操作码 (0x00) 写入电话的呼叫控制点特征。这会指示您的耳塞终止与电视的音频流,而手机(它是不同的发起方)将建立双向音频流来传输呼叫。
如果您拒绝来电,您的电视音频流将保留,因为它没有被中断 - 您的耳塞只会将其本地生成的铃声与电视音频混合。这是一种更清晰的用户体验,但这确实意味着您的耳塞会对您的手机发出不同的铃声。
如果耳塞可以执行文本到语音的转换,则可以增强带外铃声的使用,允许它说出来电特征中包含的电话号码作为呼叫警报的一部分。如果电话支持可选的友好名称特征,其中包含电话联系人列表中的来电者姓名文本,则也可以在耳塞中说出。
呼叫警报的最后一个微妙之处是电话可以设置为静音模式,其中传入的铃声不会发送到电话(或 PC)的扬声器,而是将通知留给Acceptor。呼叫控制client可以通过读取状态标志特征来确定这一点以及电话是否支持带内铃声,如表 9.4 所示。
Bit | Description | Value |
---|---|---|
0 | Inband Ringtone | 0 = disabled 1 = enabled |
1 | Silent Mode | 0 = disabled 1 = enabled |
2 - 15 | RFU | Reserved for Future Use |
如果禁用带内铃声,则呼叫控制client通常会在通知呼叫状态特征已转换为传入状态时宣布传入呼叫。请注意,这包括不是Acceptor的呼叫控制client。例如,包含呼叫控制client的智能手表可能会振动或响铃,尽管它不能接受音频流。这突出了呼叫控制状态机与 ASE 状态机没有直接连接的事实。一个不会直接触发另一个。将呼叫控制状态链接到音频流管理完全取决于电话应用程序或操作系统。
如果 Status Flags 特性显示静音模式已启用,则表示不会在手机上播放铃声。根据带内铃声(位 0)的状态,它可以使用音频流或作为带外铃声发送到acceptor,或两者兼而有之。如果两者都启用,则由 Acceptor 决定使用哪个。
值得记住的是,接受或拒绝呼叫以及所有其他状态转换都可以在呼叫控制server(即电话或 PC)以及呼叫控制client上执行。所有连接的呼叫控制client都具有平等的访问权限;任何改变状态的动作都会产生一个通知。
9.3.4 终止呼叫
任何呼叫控制client、电话上的用户操作或远程呼叫者都可以终止呼叫。它也可能由于各种原因而丢失,例如电话承载网络上的故障或信号丢失。每当呼叫终止时,呼叫控制server将使用终止原因特性通知呼叫控制client终止原因。与类似的特征一样,它包括用于识别呼叫和终止原因的 Call_Index,如图 9.8 所示。
如果多个呼叫被终止,就像在加入呼叫的网络问题的情况下可能发生的那样,则为每个 Call_Index 发送单独的终止原因通知。终止原因见
Reason_Code | Reason |
---|---|
0x00 | 发起呼叫的 URI 格式不正确 |
0x01 | 呼叫失败 |
0x02 | 对方结束通话 |
0x03 | server结束通话 |
0x04 | 线路忙 |
0x05 | 网络拥塞 |
0x06 | client结束通话 |
0x07 | 无服务 |
0x08 | 无应答 |
0x09 | Unspecified |
0x0A – 0xFF | Reserved for Future Use |
9.3.5 其他 TBS 特性
如上所述,TBS 包含大量其他用于呼叫控制server角色的特征。这些特征提供了有关电话呼叫的更详细信息。它们可以被更复杂的client读取,例如 carkits,它可以通过镜像原始电话应用程序中可用的信息级别来使用它们来复制电话的用户体验。
表 9.6 提供了上面未涵盖的附加特性的列表。所有这些都是 GTBS 或 TBS 实例必须支持的,但承载信号强度特性及其相关承载信号强度报告间隔特性除外。它们都在电话承载服务spec中进行了描述。
Characteristic Name | Description |
---|---|
Bearer Provider Name | Telephony service. E.g., Vodafone, T-Mobile |
Bearer Uniform Caller Identifier | UCI, e.g., skype, wtsap, from Assigned Numbers |
Bearer Technology | As displayed on the phone. E.g., 2G, 3G, Wi-Fi |
Bearer Signal Strength (Optional) | Signal strength from 0 (no signal) to 100 |
Bearer Signal Strength Reporting Interval | How often the signal strength is reported |
Bearer URI Schemes Supported List | A list of supported URI schemes |
Bearer List Current Calls | A list of all current calls and their state |
Content Control ID (CCID) | A CCID value which remains static until a service change |
Incoming Call Target Bearer URI | The incoming URI of the call. E.g., your phone’s number. |
有相应的过程来读取呼叫控制profile中的所有 TBS 特征。尽管对 TBS 中大多数特性的支持是强制性的,但唯一强制性的呼叫控制过程是读取呼叫状态过程。这反映了这样一个事实:对于具有受限用户界面的设备,例如助听器和耳塞,大多数控制操作很可能发生在手机上。
9.4 MCS 和 MCP
一旦您了解了电话控制,媒体控制spec就会非常熟悉。媒体控制profile定义了两个角色——媒体控制client和媒体控制server。后者驻留在initiator上,其中媒体控制服务定义了一个用于媒体播放的状态机(如图 9.9 所示),以及用于通知它正在做什么的大量特征。
对于媒体来说,玩家通常位于无活动状态,选择轨道时移至暂停状态,从中可以从中过渡到播放。从 Playing 开始,它可以通过停止它返回到 Paused,或者通过发出 Fast Forward 或 Fast Rewind 命令移动到 Seeking 状态。状态机中没有停止状态或命令。对于数字媒体,停止和暂停命令之间没有真正的区别。这种差异可以追溯到模拟设备,其中 Stop 关闭了唱片或盒式录音机的电机,而 Pause 让电机运行并将触控笔或播放头从播放介质上抬起。当一切都在数字内存中时,操作是相同的。
9.4.1 group和track
三种主要状态——Paused、Playing 和 Seeking 仅在选择了当前track时才有效,这使我们想到了track和group的概念,这是 MCS 的关键部分。图 9.10 说明了这个概念,显示了组的层次结构,其中包含轨道。定义这些结构的方式完全取决于实现,但最好将组可视化为传统专辑,其中track是单独的歌曲。组可以嵌套成为更大组的一部分,因此由贝多芬的全部作品组成的父组可能包含管弦乐、室内乐、钢琴、声乐作品等的子组,每个子组都可以包含更多子组的集合。 MCS 所要求的只是有一个定义的结构来创建从第一组开始到最后一组结束的播放顺序。
组包含轨道,轨道也可能包含段。大多数 MCP 控件在轨道上运行,这是大多数人认为的唱片或 CD 上的传统轨道。具体来说,状态机的操作集中在当前轨道上。 Track 的关键元素如图 9.11 所示,它们是 Track Duration、距 Track 两端的偏移量和播放位置。
9.4.2 对象类型和搜索
MCP 和 MCS 包含许多支持复杂用户界面的功能,例如汽车 AV 系统的屏幕。其中大部分基于现有的BLE 对象传输服务 (OTS),它允许扩展信息与组和轨道相关联。这包括扩展名称、图标和 URL,可用于获取更复杂的对象,例如专辑封面。 OTS 也用于返回搜索结果。 MCS 允许一些非常全面的搜索功能。您可以使用track名称、艺术家姓名、专辑名称、组名称、最早年份、最新年份和流派的组合进行搜索。有关这些的更多信息,请查看 MSC spec。它们在短期内不太可能在产品中使用,因此我将跳过细节并专注于媒体控制的关键方面。
9.4.3 播放track
解释了 Groups 和 Tracks 的结构后,我们可以看看媒体控制是如何工作的。一旦选择了轨道,这通常是媒体播放器上的用户操作,播放器将使用 Track Changed 特性通知其所有连接的client。这个特性没有任何价值,即它是空的,但它是媒体播放器现在有一个当前轨道的声明,因此client可以开始控制它。client可以读取轨道标题特征和轨道持续时间特征。它还可以读取轨道位置,该位置从轨道开始以 10 毫秒的分辨率返回。 (允许的最长跟踪持续时间刚刚超过 16 个月。)
client现在可以使用表 9.7 中显示的值写入媒体控制点特征。
Opcode | Name |
---|---|
0x01 | 播放 |
0x02 | 暂停 |
0x03 | 快退 |
0x04 | 快进 |
0x05 | 停止 |
当前track开始播放后,server应通知track位置特征,以告知client当前track位置。通知的频率取决于执行情况。
另一组操作码可用于在当前轨道上移动,如表 9.8 所示。
Opcode | Name | Parameters |
---|---|---|
0x10 | Move Relative | 32 bit signed integer |
0x20 | Previous Segment | None |
0x21 | Next Segment | None |
0x22 | First Segment | None |
0x23 | Last Segment | None |
0x24 | Goto Segment | 32 bit signed integer |
媒体控制服务允许在轨道内定义段。每个段都包含一个名称和距轨道起点的绝对偏移量。表 9.8 中的命令允许移动到当前轨道的特定段。这些都不允许在当前轨道之外移动。 如果参数值导致移动到当前轨道之外,则结果将仅限于将位置移动到轨道的开头或轨道的结尾,但该轨道仍然是当前轨道。
发出停止命令将导致当前track失效,因此在再次使用表 9.7 中的任何命令之前,用户需要选择另一个track作为当前track。
另外两组操作码允许选择不同的轨道作为当前轨道。
当选择另一个组时,由命令产生的当前组的第一个track成为当前的track。
所有段、轨道和组都从零开始编号。在使用 Goto 操作的情况下,正值“n”相当于转到第一项,然后执行下一项操作码 n-1 次。负值相当于到最后一项,执行前一项操作码 n-1 次。
移动到新轨道使其成为当前轨道并将其置于图 9.9 状态机的暂停状态。
仅强制支持媒体控制点特性中的至少一个操作码。任何实现都不太可能如此简单,但client可以通过读取支持的媒体控制点操作码特性来检查server支持的内容。这是一个位域,指示server支持哪些操作码。
与控制点操作码一样,client写入操作码并在媒体控制点特征中接收操作通知,其中 Result_Code 指示成功、不支持操作码或媒体播放器不活动。一旦server完成了请求,如果其值发生更改,它还将通知该操作的适当特征。
9.4.4 修改播放
媒体控制服务有几个用于修改播放和搜索的简洁功能。其中第一个是使用播放速度特性请求更改播放速度的能力。这可以由client编写以请求当前track播放得更快或更慢。该特征的参数是一个8位有符号整数“p”,取值范围为-128到127,其中请求的实际播放速度为:
𝑠
𝑝
𝑒
𝑒
𝑑
=
2
p
64
𝑠𝑝𝑒𝑒𝑑 = 2^\frac{p}{64}
speed=264p
即,速度是 2 的 (p/64) 次方。这给出了 0.25 到 3.957 的范围,实际上是标准速度的 1/4 到 4 倍。
播放速度是盲目的要求;client不知道是否支持“p”的值。请求后,server通知已在播放速度特性中设置的值。如果请求超出server支持的范围,则应将其设置为最接近的可用速度。如果媒体源是直播或流式传输,则播放速度特性值可以固定为值 1。完全由实现来决定如何调整速度以及是否保持音频数据的音高。
另一个可以改变的特性是搜索速度,通过将一个有符号整数值写入搜索速度特性。这用作当前播放速度的倍数,正值表示快进,负值表示快退。搜索速度值应用于当前播放速度,而不是默认播放速度,其中 p 的值为 0。搜索速度值为 0 表示搜索速度与具有值的播放速度相同p = 0,与当前播放速度无关。
在搜索期间,应通知 Track Position 特性以提供当前 Track Position 的指示。通知的频率由实施决定。当track位置到达当前track的开始或结束时,搜索将停止。
在搜索时,MCS 声明不应播放任何音频数据。但是,描述用例(不是音频流的内容)的Context类型通常不会改变。
9.4.5 播放顺序
MCS 中要介绍的最后一个功能是播放顺序。播放顺序特性提供了十种不同的方式来播放track。当您玩整个组时,它们中的大多数都涵盖了游戏顺序。选项列在表 9.10 中。
Value | Name | Description |
---|---|---|
0x01 | Single once | Play the current track once |
0x02 | Single repeat | Play the current track repeatedly |
0x03 | In order once | Play all of the tracks in a group in track order |
0x04 | In order repeat | Play all of the tracks in a group in track order, then repeat |
0x05 | Oldest once | Play all of the tracks in a group once, in ascending order of age |
0x06 | Oldest repeat | Play all of the tracks in a group in ascending order of age, then repeat |
0x07 | Newest once | Play all of the tracks in a group once, in descending order of age |
0x08 | Newest repeat | Play all of the tracks in a group in descending order of age, then repeat |
0x09 | Shuffle once | Play all of the tracks in a group once, in random order |
0x0A | Shuffle repeat | Play all of the tracks in a group once, in random order, then repeat |
其中有一些细微差别。播放当前track的前两个值(0x01 和 0x02)在它们完成或停止时将当前track设置为下一track。对于 shuffle,随机化留给实现。在大多数情况下,实现不是完全随机的,而是加权的,因为听众不希望在后续循环开始时播放相同的track。这些决定留给实施。client只需发送命令。如果server不支持请求的播放顺序,例如当它不知道track的年龄时,它应该忽略该命令。
与媒体控制点特性一样,client可以通过读取支持的播放顺序特性来确定支持哪些播放顺序功能。这是一个 2 字节的位域,位域含义如表 9.11 所示
Value | Name |
---|---|
0x0001 | Single once |
0x0002 | Single repeat |
0x0004 | In order once |
0x0008 | In order repeat |
0x0010 | Oldest once |
0x0020 | Oldest repeat |
0x0040 | Newest once |
0x0080 | Newest repeat |
0x0100 | Shuffle once |
0x0200 | Shuffle repeat |
电话和媒体控制就是这样 我们的下一站是音量、音频输入和麦克风。