OM8 手机云台桥(om8 MCP 工具)
om_* 系列工具来自 om8 MCP 服务器,控制一台挂在 DJI OM8 云台上的华为手机
(HarmonyOS,app com.example.ombridge,LAN JSON-RPC 桥)。配置与本机配对信息:
~/Library/Application Support/ombridge/;回传的媒体落在
/Users/huanghang/Documents/om-downloads/。
> 工具名是下划线风格(om_status 等)——OpenAI 兼容后端(DashScope 等)不接受
> 带点的函数名。若看到 om.status 点号写法(旧文档/旧会话),同一个工具。
当前形态(2026-10-15 起:普通签名,路线 B)
- 拍照 / 录像 / 人脸跟踪全部满血;跟踪可与录像同时进行(
with_tracking: true)。 - 程序化转动云台不可用:9 个系统转动 API 需 system 签名,调用会返回 code 2003 的如实报错。
用户要转云台时,说明当前构建不支持远程转动,可用 OM8 手柄实体按键/摇杆,或人脸跟踪自动跟随。 - 方向约定(仅 system 签名构建生效,供解释旧记录用):从手机背后、与镜头同向看,
yaw 正=向右,pitch 正=向上。
常用口令映射
| 用户说 | 工具调用 |
|---|---|
| 向左/右/上/下转 N 度、回中 | 当前构建不可用(om_gimbal_rotate* 如实报 2003);给替代:实体按键/跟踪跟随 |
| 开启/停止人类追踪 | om_tracking_start / om_tracking_stop |
| 拍个照片 | om_photo(要把照片拿到电脑上用 om_capture_and_pull) |
| 开始/停止拍视频 | om_video_start / om_video_stop(要传回电脑用 om_video_stop_and_pull) |
| 边跟踪边录像 | om_video_start {with_tracking: true} |
| 停下/急停 | om_emergency_stop |
| 剪视频(截取某段时间) | om_video_trim {start_s, end_s}(手机端 AVCodec 流复制,不转码、不驱动 UI、不经过电脑;起点向前对齐关键帧,GOP≈1s) |
| 发抖音/快手 | om_video_publish {platforms: ["douyin", "kuaishou"]}(先存图库再走 App 发布流程并自动点发布) |
| 剪完再发("把刚才的视频剪 5 到 15 秒发抖音") | om_video_clip_publish {start_s: 5, end_s: 15, platforms: ["douyin"]} |
| 同时发两个平台 | 可一次调用 platforms: ["douyin", "kuaishou"](最新实测约 68s;仅在宿主限时很紧时才拆分) |
| 只想先到发布页、人工点发布 | 上述发布工具加 stop_at_publish_page: true |
| 把录像存进系统图库(不发布) | om_save_to_gallery(按需,幂等) |
| 列出/下载手机上的媒体 | om_media_list / om_media_pull {media_id} |
| 看状态 | om_status |
| 删除图库里的视频 | 没有 om_* 工具;用 omctl/脚本走 mediatool delete(见"删除"一节,不可逆) |
双平台与超时(重要,2026-10-19 真机教训)
本宿主(JiuwenSwarm)对单次工具调用有 300 秒硬超时(配置里已尝试放宽到 900s,未验证前按 300s 保守行事)。
> 更正(2026-10-22):最新链路同机实测 双平台约 68s,已远低于 300s;
> 配置里的 timeout_s: 900 仍是兜底。双平台可以一次调用,不必再默认拆成两腿;
> 只有宿主实际执行仍逼近超时、或需要分别检查两平台结果时才拆分。
- 双平台 = 两次调用,每次都稳进时限:
- 第一次:om_video_clip_publish {start_s, end_s, platforms: ["douyin"]}(含剪辑)
- 第二次:om_video_publish {gallery_head: true, platforms: ["kuaishou"]}(直接发图库当前头 =
刚剪出来的那条,跳过重存与守卫) - 超时 ≠ 失败:宿主放弃等待后手机端往往还在跑并且能跑完。发布类工具超时后
绝不自动重试同一条链(会真发两条)——先向用户说明情况,用om_status/问用户确认手机端实际状态。 - 超时后的补发:确认第一平台已发出、第二平台没发时,用
om_video_publish {gallery_head: true, platforms: ["<缺的平台>"]}补发图库当前那条(就是刚剪的片子)。
gallery_head: true只用于这两种场景(拆分第二腿 / 超时补发),其他情况一律走正常链路。
发布性能(2026-10-22,已同步到 Jiuwen)
- MCP 二进制和版式档案与 Codex 共用:
~/Library/Application Support/ombridge/om-mcp、device-layouts.json。 - 同一条视频直接发布的实测:优化前 83.550s → 优化后 68.430s(抖音 31.8s、快手 33.9s)。
- 已启用:
1. App 窗口级布局读取(不合并系统窗口);
2. readiness 布局复用(快手album/first_thumb,首格实测约 4.1s → 0.5–0.9s);
3. 草稿卡单路径观测(最多两帧),取消后只重试语义步骤;
4. 发布页条件轮询、桥接前台条件轮询。 - 不要重新启用以下实验(都实测有害):
- 后台预热下一 App:会改变其落地状态;
- warm start:会恢复“发布成功”原生浮层;
sendData跨 App 分享入口:草稿状态不稳定;- 复用成功确认帧作为证据:可能截到旧编辑页/系统分享面板。
- 发布证据必须来自成功后重新抓取的当前帧。详细记录见工程
docs/08_剪辑与发布.md§4.15 / §5。
发布安全守卫(重要)
- 发布是不可逆的公开行为:
om_video_clip_publish/om_video_publish会真的把作品发出去。
用户没有明确要求"直接发布"时,优先stop_at_publish_page: true跑到发布页让人工确认。 - 同一条录像重复发布/剪辑会被明确拒绝(save_to_gallery 幂等导致图库最新不是目标)。
遇到这种报错就提示用户需要新录一条,不要绕过。
剪辑与删除的硬事实
请求区间 ≠ 实际保留区间。 om_video_trim / om_video_clip_publish 是不重编码的流复制,
起点只能落在关键帧上(相机 GOP ≈1s),会向前对齐。回执里的
actual_start_ms / actual_end_ms / trimmed_duration_ms 才是实际结果——
必须按它们向用户复述("你要的后 10 秒,实际是 66.0–76.3s"),不要把请求值当成事实。
删除是不可逆的,而且没有 om_* 工具。 走 mediatool delete <media-uri>:
不进回收站、文件直接消失(真机验证:DB 行消失、/storage 下无 .Trash、按大小全盘搜索无副本)。
- 目标要用媒体库数据库定序,不要扫目录:回收站里的资产仍留在磁盘上有 mtime,
目录扫描会让序号整体错位(2026-10-21 实测踩到)。取media_type=2 且 date_trashed=0 且 date_deleted=0,
按date_added倒序。 - 图库资产的
display_name等于沙盒文件名,可据此连带删除沙盒副本。 - 永远不要拿真实素材试删除功能,要试就造合成项:
printf x > /data/local/tmp/T.mp4; mediatool send /data/local/tmp/T.mp4 -urf。
(2026-10-21 曾因为用真实视频当样本,永久删掉了一条用户素材。) - 参考实现在项目
om8-video-ops/scripts/om8_gallery.py
(--top/--nth列表,--delete N永久删除,序号与图库 App 一致)。
屏幕状态:别拿"暗帧"当"屏幕灭了"(2026-10-21 修)
电源键是开关:屏幕亮着的时候按它,会把屏幕关掉。而黑屏/锁屏上注入的点击会被静默丢弃,
流程却照样报成功——这正是 2026-10-20 误发作品的温床。
IsDark() 那种"看截图中心是否够黑"的判据不可靠,两个方向都错过(Mate 80 Pro 实测):
抖音"发现通讯录朋友"页是近黑背景,IsDark 0.97 但屏幕是亮的;真正熄屏时反而只有 0.34。
错判的后果是流程自己按电源键把正在工作的屏幕关掉(一次发布流程里发生了两次,日志表现为
"确认期间屏幕熄灭 → 唤醒 → 上滑后仍偏暗")。
正确做法:直接问平台,不要猜:
hdc shell "hidumper -s DisplayPowerManagerService -a '-a'" # Display Id=0 State=2 亮 / State=0 灭
State=2(亮)→ 绝不按电源键;State=0(灭)→ 才执行唤醒序列;- 读不到 → 只做
power-shell wakeup(对亮屏无害),不按键。
运维排障(桥连不上 / RPC 失败时)
- 息屏会杀掉桥接 HTTP 服务:先亮屏。hdc 路径
/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony/toolchains/hdc(不在 PATH)。
唤醒并拉回桥接:hdc tconn 192.168.43.5:8710 && hdc shell aa start -a EntryAbility -b com.example.ombridge。 - AOD ≠ 锁屏:上滑解锁 (640,2500)→(640,500)。但先确认屏幕是真的灭(见上一节)——
如果屏幕亮着,keyEvent Power只会把它按灭。 - 拍照冷启动后第一张可能被设备 CameraService 拒(7400201),客户端已带一次重试;再失败等几秒重试一次,
不要连续重锤。 - "开了跟踪但云台不动"(2026-10-19 真机确认):分两步判断——
a. 先看om_status的faces_now:没人入画时云台正确地不动;人在画面中央静止时它也基本不动,
人走动才会跟。让用户走到镜头前/走动一下再下结论。
b. 有人入画但还不跟:拍一张照片(om_photo)重新点亮人脸流——相机空闲后人脸流会休眠,
下一次拍照才恢复(已知平台行为,不限于录像后)。锁会在 ~1s 内重新咬合,之后 faces_seen 应以
~30+/秒爬升、云台开始跟随。 - 命令行等价物:
/Users/huanghang/Documents/Codex/2026-10-10/harmonynext-om8-mac-pc-agent-mac-2/bin/omctl
(status / photo / video / trim / publish 等,文档在项目 docs/)。