【Rokid AR录屏功能逆向分析:通过蓝牙HCI抓包实现CXR SDK未提供的AR录屏功能】

【Rokid AR录屏功能逆向分析:通过蓝牙HCI抓包实现CXR SDK未提供的AR录屏功能】

背景介绍

作为一名Rokid Glasses开发者,我最近在开发一个需要AR录屏功能的应用。然而,Rokid官方提供的CXR SDK中并没有直接封装AR录屏的功能。在查阅官方文档和API后,我意识到需要自己探索实现方案。

经过深入研究,我发现了通过蓝牙HCI数据包分析并结合CXR API的方法,成功实现了AR录屏功能。本文将详细介绍我的探索过程和最终解决方案。

问题分析

1. 官方SDK的限制

Rokid CXR SDK提供了丰富的AR眼镜控制功能,但在录屏方面存在以下限制:

  • 没有直接的AR录屏API
  • 现有API主要面向常规应用控制
  • 文档中未提及录屏相关功能

2. 技术思路

由于没有直接的API,我决定从以下角度入手:

  1. 分析官方应用:Rokid AI App如何实现AR录屏?
  2. 蓝牙通信分析:眼镜与手机之间通过蓝牙传输哪些控制指令?
  3. 协议逆向:能否找到录屏的控制协议?

技术探索过程

在这里插入图片描述

步骤1:蓝牙HCI数据包抓取

首先,我开启了Android设备的蓝牙HCI日志功能:

# 开启蓝牙HCI日志 adb shell setprop persist.bluetooth.btsnoopenable true adb shell setprop persist.bluetooth.btsnooplogmode full adb shell stop bluetooth adb shell start bluetooth # 从设备拉取日志 adb pull /data/misc/bluetooth/logs/btsnoop_hci.log 

步骤2:使用Wireshark分析数据包

将抓取到的HCI日志用Wireshark打开,并使用过滤器查看关键数据:

# 过滤RFCOMM协议 btrfcomm # 查看Scene_Control相关的包 frame contains "Scene_Control" 

步骤3:发现关键数据包

经过仔细分析,我发现了录屏控制的关键数据包:

开始录屏指令

02 33 00 52 00 4e 00 53 00 23 ff 93 01 00 00 00 49 05 04 75 75 53 4f 81 20 41 03 53 79 73 00 00 00 38 05 02 53 53 0d 53 63 65 6e 65 5f 43 6f 6e 74 72 6f 6c 21 7b 22 6e 61 6d 65 22 3a 22 6d 69 78 5f 72 65 63 6f 72 64 22 2c 22 6f 70 65 6e 22 3a 74 72 75 65 7d 46 

停止录屏指令

02 33 00 52 00 4e 00 53 00 23 ff 93 01 00 00 00 49 05 04 75 75 53 4f 81 20 41 03 53 79 73 00 00 00 38 05 02 53 53 0d 53 63 65 6e 65 5f 43 6f 6e 74 72 6f 6c 21 7b 22 6e 61 6d 65 22 3a 22 6d 69 78 5f 72 65 63 6f 72 64 22 2c 22 6f 70 65 6e 22 3a 66 61 6c 73 65 7d 46 

步骤4:解析协议格式

通过分析数据包,我发现了协议的结构:

Scene_Control!{"name":"mix_record","open":true/false} 

这是一个简单的JSON格式控制指令:

  • name: 场景名称,AR录屏对应mix_record
  • open: 控制开关,true开始录屏,false停止录屏

解决方案实现

基于以上分析,我利用CXR SDK现有的CxrApi构建了AR录屏控制功能:

1. 核心场景控制函数

funcontrolScene(sceneType: String, enable: Boolean, extraArgs: String =""): ValueUtil.CxrStatus{ Log.i("CxrApi","controlScene sceneType:$sceneType, enable:$enable, extraArgs:$extraArgs")var status = ValueUtil.CxrStatus.REQUEST_FAILED returntry{// 构建JSON参数val json =JSONObject().apply{put("name", sceneType)put("open", enable)if(extraArgs.isNotBlank()){put("param", extraArgs)}}val jsonString = json.toJSONString() Log.i("CxrApi","sceneJson: $jsonString")// 创建Caps对象并写入数据val caps =Caps().apply{write("Scene_Control")write(jsonString)}// 发送控制请求 status = CxrController.getInstance().request(CxrApi.getInstance().w,"Sys", caps,null) status }catch(e: Exception){ Log.e("CxrApi","controlScene error: ${e.message}") ValueUtil.CxrStatus.REQUEST_FAILED }}

2. 封装的AR录屏功能

// 封装的AR录屏功能funcontrolSystemMixRecord(toOpen: Boolean){when(controlScene("mix_record", toOpen)){ ValueUtil.CxrStatus.REQUEST_SUCCEED ->{ Log.d(TAG,"Video record ${if(toOpen)"started"else"stopped"}")} ValueUtil.CxrStatus.REQUEST_FAILED ->{ Log.e(TAG,"Failed to ${if(toOpen)"start"else"stop"} video record")} ValueUtil.CxrStatus.REQUEST_WAITING ->{ Log.e(TAG,"Requested but Glasses is not ready")}else->{ Log.e(TAG,"Unknown error")}}}// 启动AR录屏funstartARRecording(){controlSystemMixRecord(true)}// 关闭AR录屏funstopARRecording(){controlSystemMixRecord(false)}

3. 完整的使用示例

class ARRecordingActivity :AppCompatActivity(){privatelateinitvar arRecordingController: ARRecordingController overridefunonCreate(savedInstanceState: Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_ar_recording) arRecordingController =ARRecordingController()// 开始AR录屏 findViewById<Button>(R.id.btn_start_record).setOnClickListener{ arRecordingController.startARRecording()}// 停止AR录屏 findViewById<Button>(R.id.btn_stop_record).setOnClickListener{ arRecordingController.stopARRecording()}}overridefunonDestroy(){super.onDestroy()// 确保停止录屏 arRecordingController.stopARRecording()}}

技术细节说明

1. 协议栈分析

通过HCI日志分析,我了解到完整的通信协议栈:

应用层: Scene_Control{"name":"mix_record","open":true} ↓ 传输层: RFCOMM (蓝牙串口仿真协议) ↓ 数据链路层: L2CAP ↓ 物理层: 蓝牙HCI 

2. 关键发现

  • 场景名称: mix_record 表示混合录制(可能同时录制AR画面和音频)
  • 控制参数: 只需要简单的开关控制
  • 系统目标: 发送到Sys系统服务

3. 错误处理

代码中完整处理了CXR API返回的各种状态:

  • REQUEST_SUCCEED: 请求成功
  • REQUEST_FAILED: 请求失败
  • REQUEST_WAITING: 设备未就绪

使用注意事项

1. 权限要求

在AndroidManifest.xml中添加必要权限:

<uses-permissionandroid:name="android.permission.RECORD_AUDIO"/><uses-permissionandroid:name="android.permission.CAMERA"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-featureandroid:name="android.hardware.bluetooth"android:required="true"/>

2. 设备连接状态

确保设备已正确连接:

if(CxrApi.getInstance().isConnected()){// 设备已连接,可以控制}else{// 设备未连接,需要先连接 Toast.makeText(this,"请先连接Rokid眼镜", Toast.LENGTH_SHORT).show()}

3. 录屏文件位置

录制的视频默认保存在:

/sdcard/ScreenRecorder/vid-{timestamp}.mp4 

总结与展望

通过这次探索,我成功实现了以下目标:

✅ 已实现功能

  1. 通过蓝牙HCI日志分析找到了AR录屏的控制协议
  2. 利用现有CXR API实现了AR录屏控制
  3. 提供了完整的开始/停止录屏接口
  4. 完善了错误处理和状态反馈

🔮 未来展望

  1. 探索更多AR场景控制功能
  2. 研究视频流实时处理
  3. 开发AR内容创作工具链
  4. 构建AR应用开发框架

致谢

感谢Rokid提供的硬件平台和CXR SDK,虽然某些功能没有直接提供API,但通过深入的技术探索,我们仍然能够实现所需的功能。

希望这篇文章能够帮助到其他需要AR录屏功能的开发者。如果你有任何问题或改进建议,欢迎在评论区留言交流!

Read more

【薅羊毛教程】LLaMaFactory 不用本地跑!免费 GPU,一键微调大模型

【薅羊毛教程】LLaMaFactory 不用本地跑!免费 GPU,一键微调大模型

一、环境 之前介绍过本地部署LLaMaFactory微调平台(https://blog.ZEEKLOG.net/m0_73982863/article/details/159208213?spm=1001.2014.3001.5501),如果你还在为设备问题而烦恼,那就来薅羊毛吧(手动狗头)。 首先注册魔搭社区,绑定个人阿里云账号即可,详情见:https://www.modelscope.cn/my/mynotebook ;然后就可免费获得36小时GPU环境。 8核:CPU有8个核心,主要负责数据的调度和预处理;32GB:内存,数据从硬盘加载后会暂时存放这里;显存24G;(比我自己的老古董好多 T-T) Ubuntu 22.04:Linux操作系统; CUDA 12.8.1:英伟达的并行计算平台。12.8版本意味着它支持最新的RTX

AI绘画总翻车?三个步骤教你这样画

相信不少人都有过AI绘画翻车经历,明明想要生动的动作特写,结果四肢僵硬得不像样,想的是唯美古风画,生成的却是“抽象派大作”,希望看到细腻的表情,但看到的却是五官如奶油般化开 每次看到这些“牛头不对马嘴”的结果,只能扶额苦笑 “其实不是你不会用 AI,而是没摸透人物动作提示词的底层逻辑 今天就从众多智能(AI)工具中挑选一款——AiPy 手把手教你写出精准提示词 输入: 就可得到从核心要素到实战技巧的详细指南,让AI图片更有张力 🤔先破局:为什么你AI出来的图片人物动作总是“翻车”? 很多人写提示词,都停留在 “我要什么动作” 的模糊描述里,却没意识到:AI 绘画需要像导演一样,把动作的肢体细节、动态张力、情绪逻辑等全部拆解成可执行的文字指令。 ❌ 错误示范:“武士挥刀” → AI 只能生成 “一个人拿着刀”,动作无张力、细节全缺失 如果是你,你会如何进行描述? ⬇想要让图片更加生动有张力,下面这五个核心要素缺一不可 ✅ 动作类型:先明确是静态、动态还是交互

DeepSeek-R1-Distill-Llama-8B实战:快速搭建智能问答系统

DeepSeek-R1-Distill-Llama-8B实战:快速搭建智能问答系统 1. 模型介绍与优势 DeepSeek-R1-Distill-Llama-8B是一个经过知识蒸馏优化的推理模型,它在保持较小参数规模的同时,具备了强大的语言理解和生成能力。这个8B参数的模型在性能和计算资源消耗之间找到了很好的平衡点,特别适合需要快速响应和高效推理的智能问答场景。 这个模型基于DeepSeek-R1的先进技术,通过蒸馏过程将大模型的知识压缩到更小的架构中。这意味着你可以在普通的硬件环境下运行它,而不需要昂贵的专业设备。对于想要搭建智能问答系统的开发者来说,这无疑是个好消息——你既不需要担心模型太大跑不动,也不用担心效果不够好。 在实际测试中,DeepSeek-R1-Distill-Llama-8B在多个基准测试中都表现不错。特别是在数学推理、代码生成和一般问答任务上,它的表现可以媲美一些更大的模型。这使它成为搭建智能问答系统的理想选择,无论是用于教育辅导、技术支持还是日常问答,都能提供可靠的服务。 2. 环境准备与快速部署 2.1 系统要求与依赖安装 在开始之前,确保你

Stable-Diffusion-v1-5-archive入门必看:5步完成文生图生成,支持负向提示词

Stable-Diffusion-v1-5-archive入门必看:5步完成文生图生成,支持负向提示词 想试试AI画画,但被复杂的安装和配置劝退?今天,我们就来聊聊一个让你能“开箱即画”的经典工具——Stable Diffusion v1.5 Archive。它就像一个封装好的“绘画工具箱”,你不需要懂代码,打开网页就能用。这篇文章,我就带你从零开始,只用5个步骤,亲手生成你的第一张AI画作,并且掌握“负向提示词”这个让画面更精准的秘密武器。 1. 认识你的AI画板:Stable Diffusion v1.5 Archive 在开始动手之前,我们先花一分钟了解一下你即将使用的工具。Stable Diffusion v1.5 Archive,你可以把它看作是AI绘画领域的一个“经典复刻版”。 它基于非常成熟的Stable Diffusion 1.5模型,这个版本在社区里经过了海量图片和提示词的训练,虽然不像最新模型那样在某些特定风格上极致惊艳,但它胜在稳定、通用、可控性强。