设备连接后,黑猫投屏在本机启动 HTTP 与 WebSocket 服务,把投屏、控制、无障碍与识别能力开放成 62 个 REST 接口。curl、PowerShell、Python、C#、易语言、按键精灵、AutoHotkey——会发 HTTP 请求就能用。
服务地址:http://127.0.0.1:7799(HTTP)与 ws://127.0.0.1:7800/ws/events(WebSocket,端口 = HTTP + 1)。仅监听本机回环,无需鉴权,软件登录后即用。
# 健康检查 curl http://127.0.0.1:7799/api/health # 设备列表 curl http://127.0.0.1:7799/api/devices # 点击屏幕中心(活跃设备,归一化坐标) curl -X POST http://127.0.0.1:7799/api/a11y/tap \ -H "Content-Type: application/json" \ -d '{"coord_type":"norm","x":0.5,"y":0.5}' # 查找「登录」按钮出现后点击 curl -X POST http://127.0.0.1:7799/api/a11y/wait-and-click \ -d '{"selector":{"text":"登录","clickable":true},"timeout_ms":8000}'
import requests BASE = "http://127.0.0.1:7799" def api(path, **body): return requests.post(f"{BASE}{path}", json=body, timeout=30).json() # 等待「登录」按钮出现并点击 api("/api/a11y/wait-and-click", selector={"text": "登录", "clickable": True}, timeout_ms=8000) # 本地验证码识别(无 image 时自动抓当前画面) api("/api/captcha/recognize", type="CharMixed")
{ "ok": true, "data": ... };失败时 ok: false 并返回 error 描述。x: 0.5, y: 0.5 永远是屏幕正中。path 传设备序列号;缺省时作用于「活跃设备」。| 接口 | 说明 |
|---|---|
GET/api/health | 健康检查,返回服务版本与在线设备数 |
GET/api/devices | 设备列表(仅 AOA 已连接设备),含分辨率、无障碍开关、活跃标记 |
POST/api/active | 切换活跃设备 |
POST/api/frame/grab | 抓取当前视频帧(共享内存引用),可指定 region |
GET/api/session/status | 会话状态查询 |
GET/api/root/status | 设备 root 状态查询 |
POST/api/device/find | 查找设备 |
全部经 AOA HID 通道注入,坐标 0-1 归一化,滑动自带多帧插值与仿人抖动。
| 接口 | 说明 |
|---|---|
POST/api/hid/touch | 原始触摸事件(down / move / up 三段组成完整手势;finger_id 支持多指) |
POST/api/hid/click | 单次点击,内部完成按下、保持、抬起 |
POST/api/hid/swipe | 快速滑动,插值多帧 move 并带仿人抖动 |
POST/api/hid/drag | 慢速拖拽 |
POST/api/hid/syskey | 系统按键(返回 / 主页 / 最近任务 / 音量等) |
| 接口 | 说明 |
|---|---|
POST/api/ime/paste | 向手机输入法粘贴文本(中文友好,绕开剪贴板嗅探) |
POST/api/ime/clear | 清空输入法编辑框 |
POST/api/ime/read | 读取输入法编辑框文本 |
POST/api/apps/list | 已安装应用列表 |
POST/api/apps/launch | 启动指定应用 |
POST/api/file/send | 文件推送(下载 / 图片 / 视频 / 相册四目录;多设备并行) |
POST/api/clipboard/get | 读取设备剪贴板 |
POST/api/clipboard/set | 写入设备剪贴板 |
Android 无障碍服务的完整 REST 化。查询类读屏幕,等待类把「轮询」变「一句话」,动作类写屏幕。
| 分组 | 接口 |
|---|---|
| 查询类 | tree 节点树 · find / find-first 选择器查找 · exists 存在判断 · text 读文本 · windows 窗口枚举 · notifications 通知列表 · focus-info 焦点信息 · package 当前应用 · capability 能力查询 · device-find / device-wait 设备级查找等待 |
| 等待类 | wait 等待节点出现 · wait-and-click 出现即点(带超时) |
| 动作类 | tap / double-tap / click / long-click · click-ex / long-click-ex 坐标增强版 · swipe / drag / scroll · input / paste 文本写入 · copy / cut / select / set-selection / clear-selection · focus / clear-focus · collapse / expand · action 任意节点动作 · batch 批量动作 · back / home / recents / quick-settings / notifications / open-settings 系统导航 |
# 读出当前界面的节点树 POST /api/a11y/tree # 等待「登录」可点击节点出现,出现即点 POST /api/a11y/wait-and-click { "selector": { "text": "登录", "clickable": true }, "timeout_ms": 8000 }
一个接口覆盖五类验证码:字符 / 数字 / 字母 / 滑块缺口 / 点选。本地 ONNX 推理(DirectML 加速,任意 DX12 显卡可用),不依赖在线接口;不传 image 时自动抓取当前设备画面。
// 字符类:返回文本 { "image": "iVBORw0KGgo...", "type": "CharMixed" } // → { "ok": true, "data": { "text": "x8Gk", "elapsed_ms": 42 } } // 滑块类:返回缺口偏移(nx 为归一化偏移,直接喂 swipe) { "path": "设备序列号", "type": "Slide", "slider": "iVBORw...", "region": { "x": 0, "y": 0.25, "width": 1, "height": 0.33 } } // → { "data": { "offset": 187, "nx": 0.358, "elapsed_ms": 12 } } // 点选类:返回目标框中心归一化坐标 + 置信度 { "image": "iVBORw...", "type": "Click" } // → { "data": { "boxes": [ { "nx": 0.068, "ny": 0.103, "score": 0.81 } ] } }
每台设备的视频帧实时写入一个 Windows 命名共享内存,格式为标准 24bpp BMP,命名形如 Local\MofeiFrame_{vid}_{pid}_{bus}{addr}_{serial}。外部进程一次 OpenFileMappingW 长期保活复用——零拷贝、不丢帧、不占额外 CPU。
/api/frame/grab 可按需取整帧或指定区域ws://127.0.0.1:7800/ws/events。握手后服务端先推 hello,再把现有设备逐一回放为 device.online,之后增量推送——新客户端连上即获得全量状态。所有事件统一信封 { "type", "ts", "data" }。
| 事件 | 说明 |
|---|---|
hello | 握手成功即下发:服务版本 + 当前在线设备数 |
device.online | 设备接入(含品牌、型号、别名、分辨率、无障碍开关) |
device.offline | 设备断开 |
device.resize | 设备分辨率 / 横竖屏变化 |
device.active | 活跃设备切换 |
a11y.event | 无障碍事件实时推送 |
import asyncio, json, websockets async def main(): async with websockets.connect("ws://127.0.0.1:7800/ws/events") as ws: while True: evt = json.loads(await ws.recv()) if evt["type"] == "device.online": print("上线:", evt["data"]["alias"]) asyncio.run(main())
GET 4 条 + POST 58 条,与程序内 BuildRoutes() 逐条对齐;另有内置文档页与 4 条内部运维路由不在此列。
| 方法 | 路径 | 方法 | 路径 |
|---|---|---|---|
| GET | /api/health | GET | /api/devices |
| GET | /api/session/status | GET | /api/root/status |
| POST | /api/active | POST | /api/frame/grab |
| POST | /api/device/find | POST | /api/file/send |
| POST | /api/hid/touch | POST | /api/hid/click |
| POST | /api/hid/swipe | POST | /api/hid/drag |
| POST | /api/hid/syskey | POST | /api/ime/paste |
| POST | /api/ime/clear | POST | /api/ime/read |
| POST | /api/apps/list | POST | /api/apps/launch |
| POST | /api/clipboard/get | POST | /api/clipboard/set |
| POST | /api/captcha/recognize | POST | /api/a11y/* × 41 |
完整的 41 个无障碍接口逐条展开见上方无障碍接口一节;每个接口的参数、错误码与示例以程序内置文档为准(见下)。
软件运行时自带一套自包含离线文档网页:浏览器打开 http://127.0.0.1:7799/ 或 /docs 即可查看与程序版本完全一致的全部接口定义;/docs.md 可直接取原始 Markdown。无外网、无 CDN,内网环境照常可用。
curl http://127.0.0.1:7799/docs.md -o heimao-api.md