当前位置: 首页 > news >正文

蓝牙音视频远程控制协议(AVRCP) command跟response介绍

 零.声明

本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:

第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。

第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等

第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。

第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)

第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展

第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。

另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。

-------------------------------------------------------------------------------------------------------------------------

蓝牙视频教程(跟韦东山老师合作):

https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.20.5aeb41f98e267j&id=693788592796

蓝牙交流扣扣群:765961169

Github代码:GitHub - sj15712795029/bluetooth_stack: 这是一个开源的双模蓝牙协议栈(bluetooth.stack)(btstack),可以运行在STM32,Linux.,包含HCI,L2CAP,SDP,RFCOMM,HFP,SPP,A2DP,AVRCP,AVDTP,AVCTP,OBEX,PBAP等协议,后续会继续维护,以达到商用的目的

入手开发板:https://shop220811498.taobao.com/category-1542116976.htm?spm=a1z10.5-c-s.w4010-22329603913.7.39ca7dbe2EA0K3&search=y&catName=%C0%B6%D1%C0%BF%AA%B7%A2%B0%E5#bd

蓝牙学习目录:一篇文章足够你学习蓝牙技术,提供史上最全的蓝牙技术(传统蓝牙/低功耗蓝牙)文章总结,文档下载总结(2020/12/11更新)_Wireless_Link的博客-CSDN博客_蓝牙eir

--------------------------------------------------------------------------------------------------------------------------

一. AVRCP command跟response

AVRCP特定的command有以下几种:

这么多PDU,我们不会一一介绍,只介绍几个典型的,其他的自己举一反三。

1. Capabilities

这个下面一共有一个实现

这个是AVRCP controller发给target的,来获取对端设备的能力,包括公司名称以及支持的event.整个数据格式如下:

获取公司ID response的格式为:

获取支持event的response格式为:

其中Capability EventID有:

我们介绍到notify的时候会详细介绍以上几个

我们结合前面的讲的vendor dependent格式来举例看下整个封包格式:

实际应用中我们一般只会用到Get Capabiliby for event,来获取对端支持的event,方便注册notify,可以看到上图支持播放状态改变,歌曲改变,播放器设置改变。当然在一般的代码中也会先获取支持的company然后再获取支持的event列表!

2. Notifications

2.1 GetPlayStatus

这个命令是controller像target发送获取播放状态的命令,返回值包括歌曲总长度,歌曲当前进度,以及播放状态,一共占用9byte(4byte歌曲长度,4byte当前进度,1byte播放状态)

我们来看下一个btsnoop

2.2 RegisterNotification

这个就是CT像TG注册消息,然后TG有对应的更新会通知,具体消息就是我们之前get capability with event的消息(需要注意的是:每次注册只能一次生效,收到change后要重新注册)我们在来贴下

我们来看下command、response的举例

我们来看一个流程图

下面我们就EVENT ID一个个来说下

EVENT_PLAYBACK_STATUS_CHANGED:播放状态改变,有以下值

EVENT_TRACK_CHANGED:歌曲名称改变

EVENT_TRACK_REACHED_END:歌曲到结尾

EVENT_TRACK_REACHED_START:歌曲开始

EVENT_ PLAYBACK_POS_CHANGED:歌曲播放进度变化

占4byte数据,是ms级别

EVENT_BATT_STATUS_CHANGED:电量状态改变,有以下值

EVENT_SYSTEM_STATUS_CHANGED:系统状态改变,有以下值

VENT_ PLAYER_APPLICATION_SETTING_CHANGED:播放器设置改变

其中AttributeID跟value对应如下:

3. Metadata Attributes for Current Media Item

这个主要是获取歌曲信息的(包括名称/专辑名/歌手名/歌曲索引/歌曲总个数等等)

AttributeID列表如下:

根据个数填上ID来获取不同的属性子项

注意两点:

  1. 如果格式填0,那么获取所有的属性
  2. 部分手机+部分播放器,比如iphone11+QQ音乐,Title会动态更新歌词

4. Volume handling

绝对音量用1个byte来表示,最高位(bit7)保留使用,所以范围是0x0~0x7f,0x0代表0%,0x7f代表100%,所以一个可读达标0.784%,其实这里我觉得设计的有点奇怪,为啥不用一个可读是1%,这样还方便统计!当然也是个人看法啦!好了,我们来看看其中的技术细节吧!

4.1 SetAbsoluteVolume

这个是用来设置绝对音量的命令,通过Pass throught命令来发送,正常搭配A2DP sink角色的AVRCP应该做controller角色,也就是可以通知上一首/下一首/播放/暂停等功能,但是这里比较特殊,需要A2DP sink搭配的AVRCP角色是TG端,所以一般要支持这个feature,需要AVRCP要做双角色,也就是AVRCP CT/TG!另外这个命令是AVRCP CT发送给TG的,所以如果是手机连接耳机,那么是手机作为CT角色发送给耳机的TG角色,这点尤其要注意,如图所示:

4.2 Notify Volume Change

注册notification时间的消息由AVRCP的controller角色发起,AVRCP的TG角色有音量变化,会通知到CT角色,当然这里也是作为双角色来做,我们还是拿手机连接耳机这个例子来说明,也就是手机还是作为AVRCP的CT角色,耳机作为AVRCP的TG角色。如果所示:

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • filezilla软件介绍
  • 【API网关】 使用Kong、Zuul等工具实现API网关
  • 【Python系列】执行 Shell 命令的六种方法
  • Android UI:PopupWindow:源码分析:设置WindowManager.LayoutParams中的各种参数
  • 《Redis核心技术与实战》学习笔记5——内存快照RDB:宕机后,Redis如何实现快速恢复?
  • 掌握责任链模式:提升系统灵活性与扩展性的秘诀!
  • 如何在Linux系统上使用ONLYOFFICE文档编辑PDF文件
  • and design vue表格列宽度拖拽,vue-draggable-resizable插件使用
  • 软件工程(4)面向对象方法:面向对象软件工程OOSE与案例实践
  • 编程艺术的细枝末节:深入探索调用约定
  • 仿twitter社区源码推特PHP源码
  • xss靶场详解
  • Redis的数据结构——Hash表
  • 如何提升 RocketMQ 顺序消费性能?
  • 如何在Linux/Debian/Ubuntu上将WebP图片转换为PNG格式
  • 【5+】跨webview多页面 触发事件(二)
  • Akka系列(七):Actor持久化之Akka persistence
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • create-react-app做的留言板
  • CSS实用技巧干货
  • GitUp, 你不可错过的秀外慧中的git工具
  • httpie使用详解
  • java2019面试题北京
  • LeetCode29.两数相除 JavaScript
  • Mybatis初体验
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • ubuntu 下nginx安装 并支持https协议
  • 聊一聊前端的监控
  • 一起来学SpringBoot | 第三篇:SpringBoot日志配置
  • 一天一个设计模式之JS实现——适配器模式
  • 因为阿里,他们成了“杭漂”
  • 自定义函数
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • ‌JavaScript 数据类型转换
  • # dbt source dbt source freshness命令详解
  • # Maven错误Error executing Maven
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (C语言)fread与fwrite详解
  • (二)正点原子I.MX6ULL u-boot移植
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .Net 知识杂记
  • .NetCore 如何动态路由
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NetCore部署微服务(二)
  • .NET与 java通用的3DES加密解密方法
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @JoinTable会自动删除关联表的数据
  • @SuppressWarnings(unchecked)代码的作用