OpenClaw 节点屏幕共享:远程显示与控制实战

摘要:本文深入解析 OpenClaw 节点的屏幕共享能力体系,涵盖屏幕截图(screen.snapshot)、屏幕录制(screen.record)、Canvas 远程呈现与控制、实时投屏等核心功能。通过三个完整实战案例------远程桌面演示、多屏幕监控、屏幕录制与回放,展示如何利用 OpenClaw 节点命令表面(command surface)构建高效的远程协作与监控方案。文章结合 Mermaid 架构图、配置代码与 CLI 命令,帮助开发者快速掌握从节点配对到屏幕共享落地的全链路实践。


目录

    • 一、屏幕共享基础
      • [1.1 什么是 OpenClaw 节点](#1.1 什么是 OpenClaw 节点)
      • [1.2 节点配对流程](#1.2 节点配对流程)
      • [1.3 屏幕共享命令概览](#1.3 屏幕共享命令概览)
      • [1.4 命令策略双门机制](#1.4 命令策略双门机制)
    • 二、显示控制详解
      • [2.1 Canvas 远程呈现](#2.1 Canvas 远程呈现)
        • 基本呈现操作
        • [页面导航与 JavaScript 执行](#页面导航与 JavaScript 执行)
      • [2.2 Canvas 截图](#2.2 Canvas 截图)
      • [2.3 屏幕截图(screen.snapshot)](#2.3 屏幕截图(screen.snapshot))
      • [2.4 A2UI:Agent 到 UI 的实时推送](#2.4 A2UI:Agent 到 UI 的实时推送)
    • 三、远程投屏功能解析
      • [3.1 屏幕录制(screen.record)](#3.1 屏幕录制(screen.record))
      • [3.2 实时投屏架构](#3.2 实时投屏架构)
      • [3.3 批量截图与定时巡检](#3.3 批量截图与定时巡检)
    • 四、实战案例1:远程桌面演示
      • [4.1 场景描述](#4.1 场景描述)
      • [4.2 架构设计](#4.2 架构设计)
      • [4.3 实现代码](#4.3 实现代码)
      • [4.4 远程控制补充](#4.4 远程控制补充)
    • 五、实战案例2:多屏幕监控
      • [5.1 场景描述](#5.1 场景描述)
      • [5.2 多节点配置](#5.2 多节点配置)
      • [5.3 巡检脚本](#5.3 巡检脚本)
      • [5.4 监控流程图](#5.4 监控流程图)
    • 六、实战案例3:屏幕录制与回放
      • [6.1 场景描述](#6.1 场景描述)
      • [6.2 录制脚本](#6.2 录制脚本)
      • [6.3 回放与标注](#6.3 回放与标注)
      • [6.4 自动分析流水线](#6.4 自动分析流水线)
    • 七、安全与权限模型
      • [7.1 命令分类与默认策略](#7.1 命令分类与默认策略)
      • [7.2 配置授权](#7.2 配置授权)
      • [7.3 前台要求](#7.3 前台要求)
      • [7.4 macOS TCC 权限](#7.4 macOS TCC 权限)
    • 八、性能优化与最佳实践
      • [8.1 截图参数优化](#8.1 截图参数优化)
      • [8.2 录屏参数优化](#8.2 录屏参数优化)
      • [8.3 带宽与 Payload 限制](#8.3 带宽与 Payload 限制)
      • [8.4 最佳实践清单](#8.4 最佳实践清单)
    • 九、总结与展望
      • [9.1 核心能力总结](#9.1 核心能力总结)
      • [9.2 与传统方案对比](#9.2 与传统方案对比)
      • [9.3 未来方向](#9.3 未来方向)
    • [📚 参考链接](#📚 参考链接)

一、屏幕共享基础

1.1 什么是 OpenClaw 节点

OpenClaw 节点(Node)是连接到 Gateway WebSocket 的伴侣设备,包括 macOS 应用、iOS/Android 移动端以及无头主机(headless node host)。节点通过 role: "node" 身份认证,向 Gateway 暴露一组命令表面(command surface),如 canvas.*camera.*screen.*device.* 等。

图1:OpenClaw 节点架构示意图,Gateway 作为中心枢纽与多个节点建立 WebSocket 连接,每个节点暴露不同的命令表面

理解节点与 Gateway 的关系是掌握屏幕共享的前提:

概念 说明
Gateway 消息路由中心,接收聊天消息、运行模型、转发工具调用
Node 外围设备,执行本地命令(截图、录屏、Canvas 渲染等)
Command Surface 节点声明的可调用命令集合,如 screen.snapshotscreen.record
Device Pairing 节点连接 Gateway 时的身份认证与审批流程

1.2 节点配对流程

屏幕共享功能依赖节点成功配对到 Gateway。配对流程如下:
操作员CLI Gateway 节点设备 操作员CLI Gateway 节点设备 #mermaid-svg-jHo7MoGhAPIFYzj9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jHo7MoGhAPIFYzj9 .error-icon{fill:#552222;}#mermaid-svg-jHo7MoGhAPIFYzj9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jHo7MoGhAPIFYzj9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jHo7MoGhAPIFYzj9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jHo7MoGhAPIFYzj9 .marker.cross{stroke:#333333;}#mermaid-svg-jHo7MoGhAPIFYzj9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jHo7MoGhAPIFYzj9 p{margin:0;}#mermaid-svg-jHo7MoGhAPIFYzj9 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-jHo7MoGhAPIFYzj9 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-jHo7MoGhAPIFYzj9 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-jHo7MoGhAPIFYzj9 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-jHo7MoGhAPIFYzj9 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-jHo7MoGhAPIFYzj9 .sequenceNumber{fill:white;}#mermaid-svg-jHo7MoGhAPIFYzj9 #sequencenumber{fill:#333;}#mermaid-svg-jHo7MoGhAPIFYzj9 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-jHo7MoGhAPIFYzj9 .messageText{fill:#333;stroke:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-jHo7MoGhAPIFYzj9 .labelText,#mermaid-svg-jHo7MoGhAPIFYzj9 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .loopText,#mermaid-svg-jHo7MoGhAPIFYzj9 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-jHo7MoGhAPIFYzj9 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-jHo7MoGhAPIFYzj9 .noteText,#mermaid-svg-jHo7MoGhAPIFYzj9 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-jHo7MoGhAPIFYzj9 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-jHo7MoGhAPIFYzj9 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-jHo7MoGhAPIFYzj9 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-jHo7MoGhAPIFYzj9 .actorPopupMenu{position:absolute;}#mermaid-svg-jHo7MoGhAPIFYzj9 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-jHo7MoGhAPIFYzj9 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-jHo7MoGhAPIFYzj9 .actor-man circle,#mermaid-svg-jHo7MoGhAPIFYzj9 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-jHo7MoGhAPIFYzj9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} "WebSocket connect (role: node, commands: ...)" "创建设备配对请求" "openclaw devices list" "返回待审批请求列表" "openclaw devices approve <requestId>" "存储配对记录 + 授权范围" "连接成功,节点已配对" "后续 node.invoke 调用"

配对完成后,可通过 openclaw nodes status 查看节点状态:

bash 复制代码
# 查看所有节点状态
openclaw nodes status

# 查看特定节点详情
openclaw nodes describe --node my-mac-node

1.3 屏幕共享命令概览

OpenClaw 节点暴露的屏幕相关命令主要包括:

命令 功能 支持平台 需要显式授权
screen.snapshot 屏幕截图,返回 base64 图像 macOS, iOS, Android 否(默认允许)
screen.record 屏幕录制,返回 mp4 视频 macOS 是(需 gateway.nodes.allowCommands
canvas.snapshot Canvas WebView 截图 macOS, iOS, Android 否(默认允许)
canvas.present 在 Canvas 中呈现 URL 或本地文件 macOS, iOS, Android 否(默认允许)
canvas.navigate Canvas 内页面导航 macOS, iOS, Android 否(默认允许)
canvas.eval 在 Canvas 中执行 JavaScript macOS, iOS, Android 否(默认允许)

⚠️ 注意screen.record 属于隐私敏感命令,需要在 Gateway 配置中显式允许。screen.snapshot 则属于安全命令,默认即可使用。

1.4 命令策略双门机制

节点命令必须通过两道关卡才能被调用:

  1. 节点声明门 :节点在 WebSocket connect.commands 列表中声明该命令
  2. Gateway 策略门:Gateway 的平台策略允许该声明命令

#mermaid-svg-gu0EEkjEYjggIg3D{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gu0EEkjEYjggIg3D .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gu0EEkjEYjggIg3D .error-icon{fill:#552222;}#mermaid-svg-gu0EEkjEYjggIg3D .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gu0EEkjEYjggIg3D .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gu0EEkjEYjggIg3D .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gu0EEkjEYjggIg3D .marker.cross{stroke:#333333;}#mermaid-svg-gu0EEkjEYjggIg3D svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gu0EEkjEYjggIg3D p{margin:0;}#mermaid-svg-gu0EEkjEYjggIg3D .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gu0EEkjEYjggIg3D .cluster-label text{fill:#333;}#mermaid-svg-gu0EEkjEYjggIg3D .cluster-label span{color:#333;}#mermaid-svg-gu0EEkjEYjggIg3D .cluster-label span p{background-color:transparent;}#mermaid-svg-gu0EEkjEYjggIg3D .label text,#mermaid-svg-gu0EEkjEYjggIg3D span{fill:#333;color:#333;}#mermaid-svg-gu0EEkjEYjggIg3D .node rect,#mermaid-svg-gu0EEkjEYjggIg3D .node circle,#mermaid-svg-gu0EEkjEYjggIg3D .node ellipse,#mermaid-svg-gu0EEkjEYjggIg3D .node polygon,#mermaid-svg-gu0EEkjEYjggIg3D .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gu0EEkjEYjggIg3D .rough-node .label text,#mermaid-svg-gu0EEkjEYjggIg3D .node .label text,#mermaid-svg-gu0EEkjEYjggIg3D .image-shape .label,#mermaid-svg-gu0EEkjEYjggIg3D .icon-shape .label{text-anchor:middle;}#mermaid-svg-gu0EEkjEYjggIg3D .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gu0EEkjEYjggIg3D .rough-node .label,#mermaid-svg-gu0EEkjEYjggIg3D .node .label,#mermaid-svg-gu0EEkjEYjggIg3D .image-shape .label,#mermaid-svg-gu0EEkjEYjggIg3D .icon-shape .label{text-align:center;}#mermaid-svg-gu0EEkjEYjggIg3D .node.clickable{cursor:pointer;}#mermaid-svg-gu0EEkjEYjggIg3D .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gu0EEkjEYjggIg3D .arrowheadPath{fill:#333333;}#mermaid-svg-gu0EEkjEYjggIg3D .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gu0EEkjEYjggIg3D .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gu0EEkjEYjggIg3D .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gu0EEkjEYjggIg3D .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gu0EEkjEYjggIg3D .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gu0EEkjEYjggIg3D .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gu0EEkjEYjggIg3D .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gu0EEkjEYjggIg3D .cluster text{fill:#333;}#mermaid-svg-gu0EEkjEYjggIg3D .cluster span{color:#333;}#mermaid-svg-gu0EEkjEYjggIg3D div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gu0EEkjEYjggIg3D .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gu0EEkjEYjggIg3D rect.text{fill:none;stroke-width:0;}#mermaid-svg-gu0EEkjEYjggIg3D .icon-shape,#mermaid-svg-gu0EEkjEYjggIg3D .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gu0EEkjEYjggIg3D .icon-shape p,#mermaid-svg-gu0EEkjEYjggIg3D .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gu0EEkjEYjggIg3D .icon-shape .label rect,#mermaid-svg-gu0EEkjEYjggIg3D .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gu0EEkjEYjggIg3D .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gu0EEkjEYjggIg3D .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gu0EEkjEYjggIg3D :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否



调用请求
节点已声明?
❌ 拒绝: 未声明
Gateway策略允许?
❌ 拒绝: 策略禁止
✅ 执行命令

如果节点更新了声明的命令列表,需要拒绝旧的设备配对请求并审批新请求,使 Gateway 存储更新后的命令快照。


二、显示控制详解

2.1 Canvas 远程呈现

Canvas 是 OpenClaw 节点上的 WebView 容器,支持远程呈现网页内容、本地文件以及 Agent 生成的 UI(A2UI)。这是实现远程显示控制的核心载体。

基本呈现操作
bash 复制代码
# 在节点 Canvas 中打开网页
openclaw nodes canvas present --node my-mac-node --target https://example.com

# 呈现本地 HTML 文件
openclaw nodes canvas present --node my-mac-node --target ./dashboard.html

# 指定 Canvas 窗口位置和大小
openclaw nodes canvas present --node my-mac-node \
  --target https://monitor.example.com \
  --x 100 --y 100 --width 1280 --height 720

# 隐藏 Canvas
openclaw nodes canvas hide --node my-mac-node

上述命令中,--target 参数支持 URL 和本地文件路径两种形式。--x/--y/--width/--height 可选参数用于精确控制 Canvas 窗口在节点设备屏幕上的位置和尺寸,这在多窗口布局场景中非常实用。

页面导航与 JavaScript 执行

Canvas 不仅支持静态呈现,还支持动态交互:

bash 复制代码
# Canvas 内页面导航
openclaw nodes canvas navigate https://new-page.example.com --node my-mac-node

# 执行 JavaScript 获取页面信息
openclaw nodes canvas eval --node my-mac-node --js "document.title"

# 执行复杂 JS 操作
openclaw nodes canvas eval --node my-mac-node --js "
  const elements = document.querySelectorAll('.status-item');
  JSON.stringify(Array.from(elements).map(e => e.textContent));
"

canvas.eval 是实现远程控制的关键------通过注入 JavaScript,可以操作页面 DOM、触发事件、读取状态,从而实现完整的远程交互闭环。

2.2 Canvas 截图

Canvas 截图(canvas.snapshot)返回当前 WebView 内容的 base64 编码图像,适用于获取 Agent 渲染的 UI 状态:

bash 复制代码
# PNG 格式截图
openclaw nodes canvas snapshot --node my-mac-node --format png

# JPEG 格式,控制宽度和质量
openclaw nodes canvas snapshot --node my-mac-node \
  --format jpg --max-width 1200 --quality 0.9

返回数据结构为 { format, base64 },CLI helper 会自动将 base64 解码写入临时文件并输出保存路径。

2.3 屏幕截图(screen.snapshot)

与 Canvas 截图不同,screen.snapshot 捕获的是节点设备的整个屏幕内容,而非仅 Canvas WebView 区域。这是远程桌面监控的基础能力。

bash 复制代码
# 通过底层 invoke 调用屏幕截图
openclaw nodes invoke --node my-mac-node \
  --command screen.snapshot \
  --params '{}'

💡 Canvas vs Screen 截图canvas.snapshot 仅捕获 WebView 内容,文件更小、速度更快;screen.snapshot 捕获全屏,包含所有窗口和桌面元素,信息更完整。根据场景选择合适的截图方式。

2.4 A2UI:Agent 到 UI 的实时推送

A2UI(Agent-to-UI)是 Canvas 上的高级功能,允许 Agent 实时推送结构化 UI 内容到节点设备:

bash 复制代码
# 推送文本内容
openclaw nodes canvas a2ui push --node my-mac-node --text "操作完成:部署成功 ✅"

# 推送 JSONL 格式的富 UI 内容
openclaw nodes canvas a2ui push --node my-mac-node --jsonl ./payload.jsonl

# 重置 A2UI 状态
openclaw nodes canvas a2ui reset --node my-mac-node

A2UI 的典型应用场景包括:

  • 实时状态推送:将 Agent 的执行进度、结果推送到移动端
  • 交互式表单:推送带按钮的 UI,用户点击后触发回调
  • 监控仪表盘:实时更新监控数据可视化

📱 移动端注意:iOS 和 Android 节点使用内置的 app-owned A2UI 页面渲染,按钮操作仅从该内置页面分发。Gateway 托管的 HTTP/HTTPS A2UI 页面在移动端为纯渲染模式。


三、远程投屏功能解析

3.1 屏幕录制(screen.record)

screen.record 是 OpenClaw 节点提供的屏幕录制能力,输出 mp4 格式视频。这是实现"投屏"的核心原语。

bash 复制代码
# 基础录屏:10秒,10fps
openclaw nodes screen record --node my-mac-node --duration 10s --fps 10

# 无音频录屏(适合纯屏幕操作录制)
openclaw nodes screen record --node my-mac-node --duration 10s --fps 10 --no-audio

# 多屏幕环境选择指定显示器
openclaw nodes screen record --node my-mac-node --duration 30s --fps 15 --screen 1

录屏参数说明:

参数 说明 默认值/限制
--duration 录制时长 最长 60 秒
--fps 帧率 建议 10-15
--no-audio 禁用麦克风捕获 默认包含音频
--screen 选择显示器索引(多屏环境) 默认主屏幕

⚠️ macOS 权限要求screen.record 需要授予 macOS Screen Recording 权限(TCC 系统设置)。首次使用时系统会弹出权限请求对话框。

3.2 实时投屏架构

OpenClaw 的"实时投屏"并非传统 VNC 式的持续像素流,而是基于定时截图 + Agent 分析的智能投屏模式。这种架构在带宽效率和智能理解之间取得了良好平衡。
#mermaid-svg-6HBNHMpPbly4FM8r{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6HBNHMpPbly4FM8r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6HBNHMpPbly4FM8r .error-icon{fill:#552222;}#mermaid-svg-6HBNHMpPbly4FM8r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6HBNHMpPbly4FM8r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6HBNHMpPbly4FM8r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6HBNHMpPbly4FM8r .marker.cross{stroke:#333333;}#mermaid-svg-6HBNHMpPbly4FM8r svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6HBNHMpPbly4FM8r p{margin:0;}#mermaid-svg-6HBNHMpPbly4FM8r .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6HBNHMpPbly4FM8r .cluster-label text{fill:#333;}#mermaid-svg-6HBNHMpPbly4FM8r .cluster-label span{color:#333;}#mermaid-svg-6HBNHMpPbly4FM8r .cluster-label span p{background-color:transparent;}#mermaid-svg-6HBNHMpPbly4FM8r .label text,#mermaid-svg-6HBNHMpPbly4FM8r span{fill:#333;color:#333;}#mermaid-svg-6HBNHMpPbly4FM8r .node rect,#mermaid-svg-6HBNHMpPbly4FM8r .node circle,#mermaid-svg-6HBNHMpPbly4FM8r .node ellipse,#mermaid-svg-6HBNHMpPbly4FM8r .node polygon,#mermaid-svg-6HBNHMpPbly4FM8r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6HBNHMpPbly4FM8r .rough-node .label text,#mermaid-svg-6HBNHMpPbly4FM8r .node .label text,#mermaid-svg-6HBNHMpPbly4FM8r .image-shape .label,#mermaid-svg-6HBNHMpPbly4FM8r .icon-shape .label{text-anchor:middle;}#mermaid-svg-6HBNHMpPbly4FM8r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6HBNHMpPbly4FM8r .rough-node .label,#mermaid-svg-6HBNHMpPbly4FM8r .node .label,#mermaid-svg-6HBNHMpPbly4FM8r .image-shape .label,#mermaid-svg-6HBNHMpPbly4FM8r .icon-shape .label{text-align:center;}#mermaid-svg-6HBNHMpPbly4FM8r .node.clickable{cursor:pointer;}#mermaid-svg-6HBNHMpPbly4FM8r .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6HBNHMpPbly4FM8r .arrowheadPath{fill:#333333;}#mermaid-svg-6HBNHMpPbly4FM8r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6HBNHMpPbly4FM8r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6HBNHMpPbly4FM8r .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6HBNHMpPbly4FM8r .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6HBNHMpPbly4FM8r .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6HBNHMpPbly4FM8r .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6HBNHMpPbly4FM8r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6HBNHMpPbly4FM8r .cluster text{fill:#333;}#mermaid-svg-6HBNHMpPbly4FM8r .cluster span{color:#333;}#mermaid-svg-6HBNHMpPbly4FM8r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6HBNHMpPbly4FM8r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6HBNHMpPbly4FM8r rect.text{fill:none;stroke-width:0;}#mermaid-svg-6HBNHMpPbly4FM8r .icon-shape,#mermaid-svg-6HBNHMpPbly4FM8r .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6HBNHMpPbly4FM8r .icon-shape p,#mermaid-svg-6HBNHMpPbly4FM8r .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6HBNHMpPbly4FM8r .icon-shape .label rect,#mermaid-svg-6HBNHMpPbly4FM8r .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6HBNHMpPbly4FM8r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6HBNHMpPbly4FM8r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6HBNHMpPbly4FM8r :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通知渠道
Gateway
节点设备
screen.snapshot
base64 图像
screen.record
mp4 视频
定时触发器
调用节点截图
Media Understanding
图像描述/OCR
Agent 决策
canvas.eval 远程控制
Telegram/飞书/Slack
Web Control UI

这种架构的优势:

  1. 带宽友好:截图体积远小于视频流,适合移动网络
  2. 智能理解:通过 Media Understanding 自动提取屏幕内容语义
  3. 按需控制:Agent 根据屏幕内容智能决定是否需要远程操作
  4. 多渠道通知:屏幕变化可推送到任意聊天渠道

3.3 批量截图与定时巡检

通过组合 CLI 命令和定时任务,可以实现批量截图巡检:

bash 复制代码
#!/bin/bash
# screen-patrol.sh - 屏幕巡检脚本
# 每隔 N 秒对指定节点执行截图并保存

NODE="my-mac-node"
INTERVAL=30
OUTPUT_DIR="./screen-captures"
mkdir -p "$OUTPUT_DIR"

while true; do
  TIMESTAMP=$(date +%Y%m%d_%H%M%S)
  openclaw nodes canvas snapshot --node "$NODE" --format png \
    2>/dev/null | tail -1 | xargs -I{} cp {} "$OUTPUT_DIR/capture_${TIMESTAMP}.png"
  echo "[$TIMESTAMP] 截图已保存"
  sleep "$INTERVAL"
done

这个脚本每 30 秒对节点执行一次 Canvas 截图,以时间戳命名保存到本地目录。结合 Media Understanding,可以进一步对截图进行自动分析和异常检测。


四、实战案例1:远程桌面演示

4.1 场景描述

团队技术分享会中,演讲者在 macOS 上操作演示,远程参与者通过 OpenClaw 节点实时观看演示内容。Agent 自动截取关键画面并推送到群聊渠道。

4.2 架构设计

#mermaid-svg-p1hYabctzAczjP6Z{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-p1hYabctzAczjP6Z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-p1hYabctzAczjP6Z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-p1hYabctzAczjP6Z .error-icon{fill:#552222;}#mermaid-svg-p1hYabctzAczjP6Z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-p1hYabctzAczjP6Z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-p1hYabctzAczjP6Z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-p1hYabctzAczjP6Z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-p1hYabctzAczjP6Z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-p1hYabctzAczjP6Z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-p1hYabctzAczjP6Z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-p1hYabctzAczjP6Z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-p1hYabctzAczjP6Z .marker.cross{stroke:#333333;}#mermaid-svg-p1hYabctzAczjP6Z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-p1hYabctzAczjP6Z p{margin:0;}#mermaid-svg-p1hYabctzAczjP6Z .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-p1hYabctzAczjP6Z .cluster-label text{fill:#333;}#mermaid-svg-p1hYabctzAczjP6Z .cluster-label span{color:#333;}#mermaid-svg-p1hYabctzAczjP6Z .cluster-label span p{background-color:transparent;}#mermaid-svg-p1hYabctzAczjP6Z .label text,#mermaid-svg-p1hYabctzAczjP6Z span{fill:#333;color:#333;}#mermaid-svg-p1hYabctzAczjP6Z .node rect,#mermaid-svg-p1hYabctzAczjP6Z .node circle,#mermaid-svg-p1hYabctzAczjP6Z .node ellipse,#mermaid-svg-p1hYabctzAczjP6Z .node polygon,#mermaid-svg-p1hYabctzAczjP6Z .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-p1hYabctzAczjP6Z .rough-node .label text,#mermaid-svg-p1hYabctzAczjP6Z .node .label text,#mermaid-svg-p1hYabctzAczjP6Z .image-shape .label,#mermaid-svg-p1hYabctzAczjP6Z .icon-shape .label{text-anchor:middle;}#mermaid-svg-p1hYabctzAczjP6Z .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-p1hYabctzAczjP6Z .rough-node .label,#mermaid-svg-p1hYabctzAczjP6Z .node .label,#mermaid-svg-p1hYabctzAczjP6Z .image-shape .label,#mermaid-svg-p1hYabctzAczjP6Z .icon-shape .label{text-align:center;}#mermaid-svg-p1hYabctzAczjP6Z .node.clickable{cursor:pointer;}#mermaid-svg-p1hYabctzAczjP6Z .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-p1hYabctzAczjP6Z .arrowheadPath{fill:#333333;}#mermaid-svg-p1hYabctzAczjP6Z .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-p1hYabctzAczjP6Z .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-p1hYabctzAczjP6Z .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-p1hYabctzAczjP6Z .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-p1hYabctzAczjP6Z .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-p1hYabctzAczjP6Z .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-p1hYabctzAczjP6Z .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-p1hYabctzAczjP6Z .cluster text{fill:#333;}#mermaid-svg-p1hYabctzAczjP6Z .cluster span{color:#333;}#mermaid-svg-p1hYabctzAczjP6Z div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-p1hYabctzAczjP6Z .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-p1hYabctzAczjP6Z rect.text{fill:none;stroke-width:0;}#mermaid-svg-p1hYabctzAczjP6Z .icon-shape,#mermaid-svg-p1hYabctzAczjP6Z .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-p1hYabctzAczjP6Z .icon-shape p,#mermaid-svg-p1hYabctzAczjP6Z .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-p1hYabctzAczjP6Z .icon-shape .label rect,#mermaid-svg-p1hYabctzAczjP6Z .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-p1hYabctzAczjP6Z .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-p1hYabctzAczjP6Z .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-p1hYabctzAczjP6Z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} screen.snapshot
Media Understanding
推送
推送
canvas.eval
演讲者 macOS

Canvas 呈现演示内容
Gateway
图像描述
飞书群聊
Slack 频道
远程控制

翻页/高亮

4.3 实现代码

bash 复制代码
#!/bin/bash
# remote-demo.sh - 远程演示助手
# 监听演示节点,定时截图并推送关键画面

NODE="presenter-mac"
CHANNEL="feishu:demo-group"
LAST_SCREENHASH=""

while true; do
  # 1. 截取当前屏幕
  SCREENSHOT=$(openclaw nodes canvas snapshot \
    --node "$NODE" --format jpg --max-width 1280 --quality 0.8 2>/dev/null | tail -1)

  if [ -z "$SCREENSHOT" ] || [ ! -f "$SCREENSHOT" ]; then
    echo "截图失败,等待重试..."
    sleep 5
    continue
  fi

  # 2. 计算图像哈希判断是否有显著变化
  CURRENT_HASH=$(md5sum "$SCREENSHOT" | cut -d' ' -f1)

  if [ "$CURRENT_HASH" != "$LAST_SCREENHASH" ]; then
    # 3. 屏幕内容变化,推送到群聊
    openclaw message send \
      --target "$CHANNEL" \
      --media "$SCREENSHOT" \
      --message "📢 演示画面更新 $(date +%H:%M:%S)"

    LAST_SCREENHASH="$CURRENT_HASH"
    echo "[$(date +%H:%M:%S)] 画面已推送"
  fi

  sleep 3
done

代码解析 :该脚本实现了一个轻量级远程演示推送器。核心逻辑是每 3 秒截取一次 Canvas 画面,通过 MD5 哈希比对判断画面是否发生变化。只有画面真正改变时才推送,避免重复消息轰炸。--max-width 1280 控制截图尺寸,兼顾清晰度和传输效率。推送使用 openclaw message send--media 参数,支持图片+文字组合发送。

4.4 远程控制补充

远程参与者不仅观看,还可以通过 Agent 发送控制指令:

bash 复制代码
# 演示翻页(假设演示是网页幻灯片)
openclaw nodes canvas eval --node presenter-mac --js "
  document.querySelector('.next-slide').click();
"

# 高亮当前内容
openclaw nodes canvas eval --node presenter-mac --js "
  const sel = window.getSelection();
  if (sel.rangeCount > 0) {
    const range = sel.getRangeAt(0);
    const highlight = document.createElement('mark');
    highlight.style.background = 'yellow';
    range.surroundContents(highlight);
  }
"

五、实战案例2:多屏幕监控

5.1 场景描述

运维团队需要同时监控多台服务器的状态仪表盘。每台服务器运行一个 Web 监控页面,通过多个 OpenClaw 节点分别呈现,Agent 定时巡检所有画面并汇总异常。

5.2 多节点配置

json5 复制代码
// openclaw.json - 多节点监控配置
{
  gateway: {
    nodes: {
      // 允许屏幕录制命令
      allowCommands: ["screen.record", "screen.snapshot"],
    },
  },
  tools: {
    media: {
      image: {
        // 配置图像理解模型用于自动分析截图
        models: [
          {
            type: "provider",
            provider: "openai",
            model: "gpt-4o",
            prompt: "分析这个监控仪表盘截图,指出任何异常指标或告警信息。用中文回答,不超过200字。",
            maxChars: 200,
            capabilities: ["image"],
          },
        ],
      },
    },
  },
}

配置解析 :这段 JSON5 配置做了两件事。第一,通过 gateway.nodes.allowCommands 显式允许 screen.recordscreen.snapshot 命令------因为 screen.record 是隐私敏感命令,默认不在安全命令列表中。第二,配置 Media Understanding 的图像理解模型,使用 GPT-4o 自动分析监控截图内容,maxChars: 200 限制输出长度以控制 token 消耗。这样 Agent 截图后可以自动获得图像语义描述,无需人工查看每张截图。

5.3 巡检脚本

bash 复制代码
#!/bin/bash
# multi-screen-monitor.sh - 多屏幕监控巡检

declare -A NODES=(
  ["prod-server-1"]="https://grafana.example.com/d/prod1"
  ["prod-server-2"]="https://grafana.example.com/d/prod2"
  ["staging-server"]="https://grafana.example.com/d/staging"
)

ALERT_CHANNEL="slack:ops-alerts"

for node in "${!NODES[@]}"; do
  url="${NODES[$node]}"

  # 1. 在各节点 Canvas 中呈现监控页面
  openclaw nodes canvas present --node "$node" --target "$url" \
    --width 1920 --height 1080

  # 2. 等待页面加载
  sleep 5

  # 3. 截图并分析
  openclaw nodes canvas snapshot --node "$node" --format jpg \
    --max-width 1920 --quality 0.9 2>/dev/null

  echo "[$(date +%H:%M:%S)] 节点 $node 巡检完成"
done

# 4. 汇总巡检结果(由 Agent 通过 Media Understanding 自动分析)
echo "所有节点巡检完成,Agent 正在分析截图..."

5.4 监控流程图

#mermaid-svg-rcHQSEOmD8CQgkhf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rcHQSEOmD8CQgkhf .error-icon{fill:#552222;}#mermaid-svg-rcHQSEOmD8CQgkhf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rcHQSEOmD8CQgkhf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rcHQSEOmD8CQgkhf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rcHQSEOmD8CQgkhf .marker.cross{stroke:#333333;}#mermaid-svg-rcHQSEOmD8CQgkhf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rcHQSEOmD8CQgkhf p{margin:0;}#mermaid-svg-rcHQSEOmD8CQgkhf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf .cluster-label text{fill:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf .cluster-label span{color:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf .cluster-label span p{background-color:transparent;}#mermaid-svg-rcHQSEOmD8CQgkhf .label text,#mermaid-svg-rcHQSEOmD8CQgkhf span{fill:#333;color:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf .node rect,#mermaid-svg-rcHQSEOmD8CQgkhf .node circle,#mermaid-svg-rcHQSEOmD8CQgkhf .node ellipse,#mermaid-svg-rcHQSEOmD8CQgkhf .node polygon,#mermaid-svg-rcHQSEOmD8CQgkhf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rcHQSEOmD8CQgkhf .rough-node .label text,#mermaid-svg-rcHQSEOmD8CQgkhf .node .label text,#mermaid-svg-rcHQSEOmD8CQgkhf .image-shape .label,#mermaid-svg-rcHQSEOmD8CQgkhf .icon-shape .label{text-anchor:middle;}#mermaid-svg-rcHQSEOmD8CQgkhf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rcHQSEOmD8CQgkhf .rough-node .label,#mermaid-svg-rcHQSEOmD8CQgkhf .node .label,#mermaid-svg-rcHQSEOmD8CQgkhf .image-shape .label,#mermaid-svg-rcHQSEOmD8CQgkhf .icon-shape .label{text-align:center;}#mermaid-svg-rcHQSEOmD8CQgkhf .node.clickable{cursor:pointer;}#mermaid-svg-rcHQSEOmD8CQgkhf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rcHQSEOmD8CQgkhf .arrowheadPath{fill:#333333;}#mermaid-svg-rcHQSEOmD8CQgkhf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rcHQSEOmD8CQgkhf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rcHQSEOmD8CQgkhf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rcHQSEOmD8CQgkhf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rcHQSEOmD8CQgkhf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rcHQSEOmD8CQgkhf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rcHQSEOmD8CQgkhf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rcHQSEOmD8CQgkhf .cluster text{fill:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf .cluster span{color:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rcHQSEOmD8CQgkhf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rcHQSEOmD8CQgkhf rect.text{fill:none;stroke-width:0;}#mermaid-svg-rcHQSEOmD8CQgkhf .icon-shape,#mermaid-svg-rcHQSEOmD8CQgkhf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rcHQSEOmD8CQgkhf .icon-shape p,#mermaid-svg-rcHQSEOmD8CQgkhf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rcHQSEOmD8CQgkhf .icon-shape .label rect,#mermaid-svg-rcHQSEOmD8CQgkhf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rcHQSEOmD8CQgkhf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rcHQSEOmD8CQgkhf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rcHQSEOmD8CQgkhf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

定时触发
遍历节点列表
节点1: canvas.present
节点2: canvas.present
节点N: canvas.present
canvas.snapshot
canvas.snapshot
canvas.snapshot
Media Understanding

GPT-4o 图像分析
检测到异常?
🚨 推送告警到 Slack
✅ 记录正常状态


六、实战案例3:屏幕录制与回放

6.1 场景描述

QA 团队需要录制 Bug 复现步骤,自动保存录屏并生成操作日志。录屏完成后,Agent 自动分析视频内容,生成文字描述和关键帧截图。

6.2 录制脚本

bash 复制代码
#!/bin/bash
# screen-recorder.sh - 屏幕录制与回放

NODE="qa-mac-node"
BUG_ID="${1:-BUG-$(date +%Y%m%d%H%M%S)}"
OUTPUT_DIR="./recordings/$BUG_ID"
mkdir -p "$OUTPUT_DIR"

echo "🎬 开始录制 Bug $BUG_ID ..."

# 1. 开始屏幕录制(30秒片段循环)
for i in $(seq 1 100); do
  openclaw nodes screen record \
    --node "$NODE" \
    --duration 30s \
    --fps 15 \
    --no-audio \
    2>/dev/null | tail -1 | xargs -I{} cp {} "$OUTPUT_DIR/segment_${i}.mp4"

  echo "  片段 $i 已保存"

  # 检查是否收到停止信号
  if [ -f "$OUTPUT_DIR/STOP" ]; then
    echo "⏹️ 收到停止信号,结束录制"
    break
  fi
done

# 2. 合并视频片段
echo "📦 合并视频片段..."
concat_file="$OUTPUT_DIR/concat.txt"
for f in "$OUTPUT_DIR"/segment_*.mp4; do
  echo "file '$f'" >> "$concat_file"
done

ffmpeg -f concat -safe 0 -i "$concat_file" \
  -c copy "$OUTPUT_DIR/full_recording.mp4" 2>/dev/null

# 3. 提取关键帧
echo "📸 提取关键帧..."
ffmpeg -i "$OUTPUT_DIR/full_recording.mp4" \
  -vf "fps=1/5" \
  -q:v 2 \
  "$OUTPUT_DIR/keyframe_%03d.jpg" 2>/dev/null

echo "✅ 录制完成!"
echo "  视频文件: $OUTPUT_DIR/full_recording.mp4"
echo "  关键帧目录: $OUTPUT_DIR/"
ls -la "$OUTPUT_DIR"/keyframe_*.jpg | wc -l | xargs -I{} echo "  关键帧数量: {}"

代码解析 :这是一个完整的 Bug 复现录制工具。录制采用 30 秒片段循环策略,避免单次录屏超过 60 秒的限制。通过创建 STOP 文件作为停止信号,QA 人员可以随时终止录制。录制完成后,使用 ffmpeg 合并所有片段为完整视频,并以每 5 秒一帧的频率提取关键帧截图。这些关键帧可后续通过 Media Understanding 进行自动分析,生成 Bug 描述文字。

6.3 回放与标注

录制完成后,可以通过 Canvas 回放并添加标注:

bash 复制代码
# 在 Canvas 中回放录制视频
openclaw nodes canvas present --node qa-mac-node \
  --target "file://$OUTPUT_DIR/full_recording.mp4"

# 通过 JS 控制视频播放
openclaw nodes canvas eval --node qa-mac-node --js "
  const video = document.querySelector('video');
  video.currentTime = 15;  // 跳转到15秒处
  video.pause();           // 暂停
"

# 添加标注覆盖层
openclaw nodes canvas eval --node qa-mac-node --js "
  const overlay = document.createElement('div');
  overlay.style.cssText = 'position:fixed;top:20px;left:20px;
    background:red;color:white;padding:8px 16px;
    border-radius:4px;font-size:14px;z-index:9999';
  overlay.textContent = '🔴 Bug 位置:此处点击无响应';
  document.body.appendChild(overlay);
"

6.4 自动分析流水线

#mermaid-svg-sNcnlT4phWLbdUGL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sNcnlT4phWLbdUGL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sNcnlT4phWLbdUGL .error-icon{fill:#552222;}#mermaid-svg-sNcnlT4phWLbdUGL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sNcnlT4phWLbdUGL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sNcnlT4phWLbdUGL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sNcnlT4phWLbdUGL .marker.cross{stroke:#333333;}#mermaid-svg-sNcnlT4phWLbdUGL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sNcnlT4phWLbdUGL p{margin:0;}#mermaid-svg-sNcnlT4phWLbdUGL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-sNcnlT4phWLbdUGL .cluster-label text{fill:#333;}#mermaid-svg-sNcnlT4phWLbdUGL .cluster-label span{color:#333;}#mermaid-svg-sNcnlT4phWLbdUGL .cluster-label span p{background-color:transparent;}#mermaid-svg-sNcnlT4phWLbdUGL .label text,#mermaid-svg-sNcnlT4phWLbdUGL span{fill:#333;color:#333;}#mermaid-svg-sNcnlT4phWLbdUGL .node rect,#mermaid-svg-sNcnlT4phWLbdUGL .node circle,#mermaid-svg-sNcnlT4phWLbdUGL .node ellipse,#mermaid-svg-sNcnlT4phWLbdUGL .node polygon,#mermaid-svg-sNcnlT4phWLbdUGL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sNcnlT4phWLbdUGL .rough-node .label text,#mermaid-svg-sNcnlT4phWLbdUGL .node .label text,#mermaid-svg-sNcnlT4phWLbdUGL .image-shape .label,#mermaid-svg-sNcnlT4phWLbdUGL .icon-shape .label{text-anchor:middle;}#mermaid-svg-sNcnlT4phWLbdUGL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sNcnlT4phWLbdUGL .rough-node .label,#mermaid-svg-sNcnlT4phWLbdUGL .node .label,#mermaid-svg-sNcnlT4phWLbdUGL .image-shape .label,#mermaid-svg-sNcnlT4phWLbdUGL .icon-shape .label{text-align:center;}#mermaid-svg-sNcnlT4phWLbdUGL .node.clickable{cursor:pointer;}#mermaid-svg-sNcnlT4phWLbdUGL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sNcnlT4phWLbdUGL .arrowheadPath{fill:#333333;}#mermaid-svg-sNcnlT4phWLbdUGL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sNcnlT4phWLbdUGL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sNcnlT4phWLbdUGL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sNcnlT4phWLbdUGL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sNcnlT4phWLbdUGL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sNcnlT4phWLbdUGL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sNcnlT4phWLbdUGL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sNcnlT4phWLbdUGL .cluster text{fill:#333;}#mermaid-svg-sNcnlT4phWLbdUGL .cluster span{color:#333;}#mermaid-svg-sNcnlT4phWLbdUGL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sNcnlT4phWLbdUGL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sNcnlT4phWLbdUGL rect.text{fill:none;stroke-width:0;}#mermaid-svg-sNcnlT4phWLbdUGL .icon-shape,#mermaid-svg-sNcnlT4phWLbdUGL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sNcnlT4phWLbdUGL .icon-shape p,#mermaid-svg-sNcnlT4phWLbdUGL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sNcnlT4phWLbdUGL .icon-shape .label rect,#mermaid-svg-sNcnlT4phWLbdUGL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sNcnlT4phWLbdUGL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sNcnlT4phWLbdUGL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sNcnlT4phWLbdUGL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} screen.record

屏幕录制
mp4 片段
ffmpeg 合并
完整视频
关键帧提取
关键帧 JPG
Media Understanding

GPT-4o 图像分析
操作步骤描述
异常检测
Canvas 回放
JS 标注覆盖
标注后截图
📝 Bug 报告生成


七、安全与权限模型

7.1 命令分类与默认策略

OpenClaw 对节点命令采用分级安全策略:

分类 命令示例 默认策略 说明
安全命令 canvas.*, camera.list, screen.snapshot 默认允许 只读或低风险操作
隐私敏感 camera.snap, camera.clip, screen.record 需显式授权 涉及摄像头/麦克风/录屏
高危命令 system.run, system.which operator.admin 可执行任意系统命令

7.2 配置授权

openclaw.json 中配置允许的命令:

json5 复制代码
{
  gateway: {
    nodes: {
      // 允许隐私敏感命令
      allowCommands: ["screen.record", "camera.snap", "camera.clip"],
      // 禁止特定命令(优先级最高)
      denyCommands: ["system.run"],
    },
  },
}

🔒 安全原则denyCommands 始终优先于 allowCommands 和默认策略。即使命令同时在两个列表中,denyCommands 也会生效。

7.3 前台要求

iOS 和 Android 节点要求应用处于前台 才能执行 canvas.*camera.* 命令。后台调用会返回 NODE_BACKGROUND_UNAVAILABLE 错误。

这意味着:

  • 屏幕截图需要节点应用在前台活跃
  • 屏幕录制同样需要前台状态
  • 设计监控方案时需考虑节点应用的生命周期

7.4 macOS TCC 权限

macOS 节点使用 screen.record 需要系统级 Screen Recording 权限:

  1. 打开 系统设置 → 隐私与安全性 → 屏幕录制
  2. 找到 OpenClaw 应用并勾选允许
  3. 重启 OpenClaw 节点应用使权限生效

八、性能优化与最佳实践

8.1 截图参数优化

不同场景对截图质量和尺寸的要求不同:

场景 推荐参数 说明
快速巡检 --format jpg --max-width 800 --quality 0.6 小体积,低延迟
常规监控 --format jpg --max-width 1280 --quality 0.8 平衡质量与体积
高清存档 --format png --max-width 1920 无损,大体积
移动端推送 --format jpg --max-width 640 --quality 0.7 适配小屏幕

8.2 录屏参数优化

场景 fps 音频 说明
操作演示 15 包含 需要语音讲解
Bug 复现 10 不含 纯操作步骤,无需音频
性能监控 5 不含 低帧率节省资源

8.3 带宽与 Payload 限制

OpenClaw 对节点返回的 Payload 有内置保护:

  • 照片:base64 不超过 5 MB(自动重压缩)
  • 视频片段:时长不超过 60 秒
  • Canvas 截图 :通过 --max-width--quality 控制体积

在大规模监控场景中,建议:

  1. 使用 JPEG 格式而非 PNG(体积差异可达 5-10 倍)
  2. 合理设置 --max-width(通常 1280px 足够识别内容)
  3. 采用变化检测策略,仅在画面变化时推送
  4. 利用 Media Understanding 在 Gateway 端压缩语义,只传输文字描述

8.4 最佳实践清单

  • 配对后验证openclaw nodes status 确认节点已配对且在线
  • 最小权限原则 :只 allowCommands 真正需要的命令
  • 前台保障:移动端节点确保应用在前台,或实现自动前台唤醒
  • 变化检测:截图巡检使用哈希比对,避免重复推送
  • 分段录制:长时录屏采用分段策略,每段 ≤ 60 秒
  • 错误处理 :检查 NODE_BACKGROUND_UNAVAILABLE 等错误码并重试
  • 资源清理:定期清理临时截图和录屏文件

九、总结与展望

9.1 核心能力总结

OpenClaw 节点的屏幕共享能力构建了一套完整的远程显示与控制体系:
#mermaid-svg-vGShie12i0MJIKvs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vGShie12i0MJIKvs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vGShie12i0MJIKvs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vGShie12i0MJIKvs .error-icon{fill:#552222;}#mermaid-svg-vGShie12i0MJIKvs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vGShie12i0MJIKvs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vGShie12i0MJIKvs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vGShie12i0MJIKvs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vGShie12i0MJIKvs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vGShie12i0MJIKvs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vGShie12i0MJIKvs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vGShie12i0MJIKvs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vGShie12i0MJIKvs .marker.cross{stroke:#333333;}#mermaid-svg-vGShie12i0MJIKvs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vGShie12i0MJIKvs p{margin:0;}#mermaid-svg-vGShie12i0MJIKvs .edge{stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .section--1 rect,#mermaid-svg-vGShie12i0MJIKvs .section--1 path,#mermaid-svg-vGShie12i0MJIKvs .section--1 circle,#mermaid-svg-vGShie12i0MJIKvs .section--1 polygon,#mermaid-svg-vGShie12i0MJIKvs .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section--1 text{fill:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth--1{stroke-width:17;}#mermaid-svg-vGShie12i0MJIKvs .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-0 rect,#mermaid-svg-vGShie12i0MJIKvs .section-0 path,#mermaid-svg-vGShie12i0MJIKvs .section-0 circle,#mermaid-svg-vGShie12i0MJIKvs .section-0 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-vGShie12i0MJIKvs .section-0 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-0{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-0{stroke-width:14;}#mermaid-svg-vGShie12i0MJIKvs .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-1 rect,#mermaid-svg-vGShie12i0MJIKvs .section-1 path,#mermaid-svg-vGShie12i0MJIKvs .section-1 circle,#mermaid-svg-vGShie12i0MJIKvs .section-1 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-1 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-1{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-1{stroke-width:11;}#mermaid-svg-vGShie12i0MJIKvs .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-2 rect,#mermaid-svg-vGShie12i0MJIKvs .section-2 path,#mermaid-svg-vGShie12i0MJIKvs .section-2 circle,#mermaid-svg-vGShie12i0MJIKvs .section-2 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-2 text{fill:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-2{stroke-width:8;}#mermaid-svg-vGShie12i0MJIKvs .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-3 rect,#mermaid-svg-vGShie12i0MJIKvs .section-3 path,#mermaid-svg-vGShie12i0MJIKvs .section-3 circle,#mermaid-svg-vGShie12i0MJIKvs .section-3 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-3 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-3{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-3{stroke-width:5;}#mermaid-svg-vGShie12i0MJIKvs .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-4 rect,#mermaid-svg-vGShie12i0MJIKvs .section-4 path,#mermaid-svg-vGShie12i0MJIKvs .section-4 circle,#mermaid-svg-vGShie12i0MJIKvs .section-4 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-4 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-4{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-4{stroke-width:2;}#mermaid-svg-vGShie12i0MJIKvs .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-5 rect,#mermaid-svg-vGShie12i0MJIKvs .section-5 path,#mermaid-svg-vGShie12i0MJIKvs .section-5 circle,#mermaid-svg-vGShie12i0MJIKvs .section-5 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-5 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-5{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-5{stroke-width:-1;}#mermaid-svg-vGShie12i0MJIKvs .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-6 rect,#mermaid-svg-vGShie12i0MJIKvs .section-6 path,#mermaid-svg-vGShie12i0MJIKvs .section-6 circle,#mermaid-svg-vGShie12i0MJIKvs .section-6 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-6 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-6{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-6{stroke-width:-4;}#mermaid-svg-vGShie12i0MJIKvs .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-7 rect,#mermaid-svg-vGShie12i0MJIKvs .section-7 path,#mermaid-svg-vGShie12i0MJIKvs .section-7 circle,#mermaid-svg-vGShie12i0MJIKvs .section-7 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-7 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-7{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-7{stroke-width:-7;}#mermaid-svg-vGShie12i0MJIKvs .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-8 rect,#mermaid-svg-vGShie12i0MJIKvs .section-8 path,#mermaid-svg-vGShie12i0MJIKvs .section-8 circle,#mermaid-svg-vGShie12i0MJIKvs .section-8 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-8 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-8{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-8{stroke-width:-10;}#mermaid-svg-vGShie12i0MJIKvs .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-9 rect,#mermaid-svg-vGShie12i0MJIKvs .section-9 path,#mermaid-svg-vGShie12i0MJIKvs .section-9 circle,#mermaid-svg-vGShie12i0MJIKvs .section-9 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-9 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-9{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-9{stroke-width:-13;}#mermaid-svg-vGShie12i0MJIKvs .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-10 rect,#mermaid-svg-vGShie12i0MJIKvs .section-10 path,#mermaid-svg-vGShie12i0MJIKvs .section-10 circle,#mermaid-svg-vGShie12i0MJIKvs .section-10 polygon,#mermaid-svg-vGShie12i0MJIKvs .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-10 text{fill:black;}#mermaid-svg-vGShie12i0MJIKvs .node-icon-10{font-size:40px;color:black;}#mermaid-svg-vGShie12i0MJIKvs .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .edge-depth-10{stroke-width:-16;}#mermaid-svg-vGShie12i0MJIKvs .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-vGShie12i0MJIKvs .disabled,#mermaid-svg-vGShie12i0MJIKvs .disabled circle,#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:lightgray;}#mermaid-svg-vGShie12i0MJIKvs .disabled text{fill:#efefef;}#mermaid-svg-vGShie12i0MJIKvs .section-root rect,#mermaid-svg-vGShie12i0MJIKvs .section-root path,#mermaid-svg-vGShie12i0MJIKvs .section-root circle,#mermaid-svg-vGShie12i0MJIKvs .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-vGShie12i0MJIKvs .section-root text{fill:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .section-root span{color:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .section-2 span{color:#ffffff;}#mermaid-svg-vGShie12i0MJIKvs .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-vGShie12i0MJIKvs .edge{fill:none;}#mermaid-svg-vGShie12i0MJIKvs .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-vGShie12i0MJIKvs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} OpenClaw 屏幕共享
截图
Canvas 截图
全屏截图
批量巡检
录制
screen.record
分段策略
关键帧提取
显示
Canvas 呈现
A2UI 推送
JS 远程控制
安全
命令策略双门
TCC 权限
前台要求

9.2 与传统方案对比

维度 传统 VNC/RDP OpenClaw 节点屏幕共享
连接方式 持续像素流 按需截图/录屏
带宽消耗 高(持续传输) 低(按需传输)
智能理解 Media Understanding 自动分析
多渠道推送 仅桌面客户端 任意聊天渠道
远程控制 专用协议 Canvas JS 注入
安全模型 VPN/密码 命令策略 + 设备配对 + TCC

9.3 未来方向

随着 OpenClaw 的持续演进,屏幕共享能力有望在以下方向增强:

  • 更高帧率实时投屏:突破当前 60 秒录屏限制,支持更长时间的连续录制
  • WebRTC 实时流:基于 WebRTC 的低延迟像素流,接近 VNC 体验
  • 多节点协同:多个节点屏幕拼接为虚拟大屏
  • AI 驱动的智能监控:Agent 主动识别屏幕异常并自动告警

📚 参考链接

相关推荐
是发财不是旺财19 小时前
Hermes 网关四层权限控制方案:让 AI Agent 安全地查数据库
数据库·安全·agent·openclaw·hermes
毕竟是shy哥20 小时前
Claude Code 接入 DeepSeek 保姆级教程,WSL/Linux 通用
linux·安装教程·codex·deepseek·claude code·openclaw
无心水20 小时前
【Hermes:团队、企业、生态与边界】47、Hermes 在 CI/CD 中的完整 DevOps 流水线:从 PR 审查到自动部署,让 Agent 接管你的发布流程
运维·人工智能·devops·openclaw·养龙虾·hermes·honcho
南檐巷上学21 小时前
基于地平线RDK X5的智能医药机器人系统
ubuntu·机器人·ros·机械臂·openclaw
AC赳赳老秦1 天前
OpenClaw 助力技术面试:自动生成面试题、模拟面试、整理面试知识点
开发语言·python·面试·职场和发展·自动化·deepseek·openclaw
七夜zippoe1 天前
OpenClaw 节点摄像头:远程拍照与视频录制实
音视频·视频录制·openclaw·节点摄像头·远程拍照
AC赳赳老秦1 天前
OpenClaw + 华为云自动化:批量管理云资源、生成月度云账单分析与成本优化报告
java·开发语言·javascript·人工智能·python·mysql·openclaw
无心水2 天前
17、本地多模态|Qwen-VL离线私有化提取敏感PDF完全指南
人工智能·分布式·架构·openclaw·hermes
xyz_CDragon2 天前
OpenClaw 局域网调用 Ollama 本地大模型:完整配置与踩坑指南
python·ai编程·集成学习·ollama·deepseek·openclaw