【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,我决定从以下角度入手:
- 分析官方应用:Rokid AI App如何实现AR录屏?
- 蓝牙通信分析:眼镜与手机之间通过蓝牙传输哪些控制指令?
- 协议逆向:能否找到录屏的控制协议?
技术探索过程

步骤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_recordopen: 控制开关,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 总结与展望
通过这次探索,我成功实现了以下目标:
✅ 已实现功能
- 通过蓝牙HCI日志分析找到了AR录屏的控制协议
- 利用现有CXR API实现了AR录屏控制
- 提供了完整的开始/停止录屏接口
- 完善了错误处理和状态反馈
🔮 未来展望
- 探索更多AR场景控制功能
- 研究视频流实时处理
- 开发AR内容创作工具链
- 构建AR应用开发框架
致谢
感谢Rokid提供的硬件平台和CXR SDK,虽然某些功能没有直接提供API,但通过深入的技术探索,我们仍然能够实现所需的功能。
希望这篇文章能够帮助到其他需要AR录屏功能的开发者。如果你有任何问题或改进建议,欢迎在评论区留言交流!