Skip to main content

ui-demo

录制精美的产品 UI demo 视频(camoufox-cli 驱动)。当用户需要录制演示视频、功能演示、操作教程或利益相关方展示视频时使用。输出带可见鼠标、字幕和自然节奏的 WebM 视频。

Source facts

Repository
TeamWiseFlow/xiaobei
Last source activity
October 8, 2026 at 14:42
Detected SKILL.md language
Chinese
Stars
8,596
Forks
1,461

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
4 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
ui-demo
description
录制精美的产品 UI demo 视频(camoufox-cli 驱动)。当用户需要录制演示视频、功能演示、操作教程或利益相关方展示视频时使用。输出带可见鼠标、字幕和自然节奏的 WebM 视频。
metadata
{"openclaw":{"emoji":"🎥","requires":{"bins":"[Truncated]"}}}
# UI Demo Video Recorder 用 `camoufox-cli` 探查与演习,用本技能的录制执行器(`ui-demo` 命令)录制成片:注入可见鼠标光标、底部字幕条,配自然节奏,产出 WebM。 ## 浏览器后端说明(先读) 本 skill 所有具体操作命令和示例**只针对 `target=camoufox`**(全局 `camoufox-cli` 命令 + 本技能 `ui-demo` 录制执行器)。若当前是 `target=host` 或 `target=node`:只按本 skill 的流程 / 步骤 / 提示事项执行,不要照搬下面的具体命令和示例,浏览器操作走当前后端自带的工具语义。 ## When to Use - 用户需要"演示视频"、"产品录屏"、"功能演示"或"操作教程" - 需要制作用于文档、用户引导或投资人/客户展示的视频 ## Three-Phase Process **Discover → Rehearse → Record**。禁止跳过直接录制。 **有头/无头总原则**:全程默认无头。只有两种情况用有头:① 用户明确表示要旁观(见 Phase 2 的必问环节);② 无头模式无法正常工作(页面渲染异常、必须人工过验证码等),此时改有头并告知用户原因。 **⚠️ 同一 session 的模式必须保持一致:以 `--headed` 打开后,后续每条 `camoufox-cli` 命令(包括 `eval`、`snapshot`、`screenshot`、`scroll`、cookie 导出和 `close`)都必须带 `--headed`,直到关闭 session。漏带会重启 daemon、关闭浏览器窗口并丢失当前页面。需要切换模式时,先按原模式 `close`,再按新模式 `open`。** 以下未带 `--headed` 的示例适用于无头 session;有头 session 使用时必须补上该参数。Phase 3 的 `ui-demo` 执行器创建独立浏览器,不复用演习 daemon。 --- ## Phase 1: Discover(camoufox-cli 探查) 在写录制脚本之前,用 `camoufox-cli` 逐一导航到流程中的每个页面,了解真实的页面结构。 ```bash camoufox-cli --session ui-demo --json open <url> camoufox-cli --session ui-demo --json snapshot camoufox-cli --session ui-demo --json click @e5 # 探查交互 camoufox-cli --session ui-demo --json screenshot /tmp/ui-demo-check.png ``` - 目标应用**需要登录**时,session 加 `--persistent`(登录态存 profile,演习多轮不重复登录);登录流程按 `browser-guide` 技能执行(扫码/验证码场景 `--headed`)。 - **目标:建立每个页面的字段映射表**,用于 Phase 3 脚本中的选择器。 - ⚠️ **字段映射必须落成 CSS / text 选择器**(如 `input[name="email"]`、`button:has-text("Submit")`)。snapshot 的 `@e1` ref 只在 camoufox-cli 会话内有效,**不能写进录制脚本**。定位到元素后用 snapshot 里的标签/属性信息推出稳定选择器,必要时 `eval` 验证。 每个页面重点关注: - **表单字段类型**:是 `<input>`、`<textarea>`、`<select>` 还是自定义 combobox / contenteditable? - **Select 选项**:确认实际选项值。Placeholder 选项(通常 value 为 `""` 或 `"0"`)看起来非空但实际无效,跳过。 - **按钮精确文本**:如 `"Submit"`、`"Submit Request"`、`"Save"`。 - **必填字段**:尝试提交空表单,观察验证报错。 - **动态字段**:填写某字段后,确认是否有新字段出现。 **输出**:整理每个页面的字段映射,例如: ``` /purchase-requests/new: - Budget Code: select#budget-code(4 个真实选项,第一个是 placeholder) - Desired Delivery: input[type="date"] - Context: textarea[name="context"](不是 input) - Submit: button:has-text("Submit Request") ``` --- ## Phase 2: Rehearse(演习 = 确认录制脚本) 不录制,用 `camoufox-cli` **手动走一遍完整流程**。演习的产物是**录制计划**——步骤序列、每步字幕文案、节奏、不录清单——这就是录制脚本,必须经用户确认后才进 Phase 3。 ### Step 0:必问用户是否旁观(不许跳过) 演习开始前,先问用户: > "我准备把整个演示流程演习一遍,确认录制内容。你要在浏览器窗口里**旁观演习**吗?旁观的话你可以随时提意见——重点录哪一块、不录哪一块、顺序怎么调。" - **用户要旁观** → 先 `camoufox-cli --session ui-demo --json close`,再以有头模式重开演习(viewport 与录制分辨率一致,用户看到的就是录出来的构图): ```bash camoufox-cli --session ui-demo --headed --viewport 1280x720 --json open <起始url> camoufox-cli --session ui-demo --headed --json snapshot camoufox-cli --session ui-demo --headed --json screenshot /tmp/ui-demo-check.png ``` **⚠️ 有头演习后续所有命令必须持续带 `--headed`,包括导出 cookie 和最终 `close`;漏带会重启 daemon 并丢页面。** 从有头探查进入本步骤时,先关闭旧 session 的命令也必须带 `--headed`。 旁观模式下的演习纪律: - 每一步操作**前**,在聊天里先说这一步要做什么(对应未来的字幕文案),再执行; - 节奏放慢,步与步之间留出用户开口的时间; - 用户随时提出的意见("这块重点录"、"这段跳过"、"先展示 X 再展示 Y")**即时记入录制计划**,必要时当场重走调整后的顺序给用户看。 - **用户不旁观** → 无头演习(不带 `--headed`),照常逐步走完。 - 无头演习中发现页面无法正常工作(渲染异常、验证码等)→ 改有头继续,并告知用户原因。 ### 演习内容 - 按照 Phase 1 的字段映射,逐步导航、填写、点击(`camoufox-cli --session ui-demo --json click/fill/type ...`) - 每个操作后确认页面状态符合预期(`snapshot`) - 发现不符时,修正字段映射再重试 - 需要上传文件的步骤:`camoufox-cli --session ui-demo --json upload @ref /path/to/file` > 演习的价值在于消灭"脚本假设"——字段顺序、选择器、等待时机,都在这里确认,不留到录制时爆。 ### 演习收尾(强制) 1. 把**录制计划**发给用户确认:步骤清单(每步一句话+字幕文案)、预计时长、明确不录的内容。用户认了才进 Phase 3。 2. 若 Phase 3 需要登录态,先导出 cookie,再关演习 session。以下为无头示例;**有头演习两条命令都必须加 `--headed`**: ```bash camoufox-cli --session ui-demo --json cookies export <project-dir>/cookies.json camoufox-cli --session ui-demo --json close ``` --- ## Phase 3: Record(录制执行器) 按确认后的录制计划编写 demo-steps 文件,用 `ui-demo` 命令录制。**默认无头录制**(无头下 WebM 正常产出,不需要屏幕);仅当用户要求旁观录制过程、或无头录制画面异常时加 `--headed`。 ### 运行 ```bash ui-demo --steps <project-dir>/demo-steps.mjs \ --output <project-dir>/output/demo-<feature>.webm \ --base-url http://localhost:3000 \ --cookies <project-dir>/cookies.json ``` | 参数 | 默认 | 说明 | |------|------|------| | `--steps` | 必填 | demo-steps 文件路径(ESM,默认导出 async 函数) | | `--output` | 必填 | 输出 WebM 路径 | | `--headed` | 关 | 有头录制(仅用户要求旁观或无头异常时用) | | `--viewport` | `1280x720` | 浏览器窗口尺寸。成片按窗口内容区实测裁定(略小于窗口高,如 1280x658),实际分辨率见输出报告 `resolution` 字段 | | `--base-url` | env `BASE_URL` | 注入 steps 函数的 `baseURL` | | `--cookies` | — | 演习 session 导出的 cookie 文件,录制前注入(跳过登录画面) | 退出码:0 成功 / 1 参数错或步骤出错(已录到的部分仍保存)/ 3 技能 Node 依赖或浏览器未装(按 `error` 提示修复;浏览器未装时先 `camoufox-cli install`)。 Node 依赖由统一安装流程按本技能 `package.json` 安装到技能目录;全局 `camoufox-cli` 的嵌套依赖不能替代本技能依赖。收到依赖缺失提示时,重跑统一安装流程,或执行提示中的 `npm install --prefix ... --omit=dev` 修复命令。 ### demo-steps 文件模板 ```javascript export default async function run(demo) { const { page, baseURL, showSubtitle, moveAndClick, typeSlowly, smoothScroll, pause } = demo; // Step 1 - 登录(cookies 已注入通常直接跳过;失效则走表单登录) await page.goto(`${baseURL}/dashboard`); await pause(3000); const loggedIn = await page.locator('.user-menu, .avatar').first() .isVisible().catch(() => false); if (!loggedIn) { await showSubtitle('Step 1 - 登录'); await typeSlowly('input[name="email"]', 'demo@example.com', 'Email'); await typeSlowly('input[name="password"]', 'demo-password', 'Password'); await moveAndClick('button[type="submit"]', 'Login'); await pause(4000); await showSubtitle(''); } await showSubtitle('Step 2 - 概览'); await smoothScroll(400); await showSubtitle('Step 3 - 主要流程'); // 按录制计划的操作序列…… await showSubtitle('Step 4 - 结果'); await pause(3000); await showSubtitle(''); } ``` ### 内置 helper(执行器提供,不要在 steps 里自己实现) | helper | 签名 | 行为 | |--------|------|------| | `showSubtitle` | `(text)` | 底部字幕条显示 text,置空 `''` 隐藏;显示后自动停 800ms | | `moveAndClick` | `(locator, label, {postClickDelay=800})` | scrollIntoView → 光标平滑移动到元素中心 → 点击 → 停顿;失败打 WARNING 返回 false | | `typeSlowly` | `(locator, text, label, charDelay=35)` | 点击聚焦 → 清空 → 逐字输入 | | `smoothScroll` | `(top)` | smooth 滚动到指定位置 + 停 1.5s | | `pause` | `(ms)` | 等待 | | `injectOverlays` | `()` | 手动重注入光标/字幕层。整页导航后执行器已自动重注入;SPA 内部路由切换若丢失覆盖层可手动补 | `locator` 参数接受 CSS/text 选择器字符串或 `page.locator(...)` 对象。 ### Recording Principles #### 1. Storytelling Flow 将视频规划为一个故事,默认结构: - **Entry**:登录或导航到起始点 - **Context**:浏览周围环境让观众先定向 - **Action**:执行主要工作流步骤 - **Variation**:展示次要功能(可选) - **Result**:展示结果或最终状态 #### 2. Pacing(节奏) | 时机 | 等待时长 | |------|---------| | 登录后 | 4s | | 导航后 | 3s | | 点击按钮后 | 2s | | 主要步骤之间 | 1.5-2s | | 最后一个动作后 | 3s | | 打字延迟 | 25-40ms / 字符 | #### 3. Subtitles(字幕) 字幕规范:不超过 60 字符,使用 `Step N - 动作` 格式,UI 已能说明问题时置空隐藏。 #### 4. 富文本编辑器处理(重要) 对于 `contenteditable` 富文本编辑器(如 Quill、TinyMCE 等): - **禁止使用 `fill()` 填充内容**!`fill()` 会导致编辑器无法识别内容,提交时可能丢失 - 正确做法:先 `click()` 聚焦,再 `pressSequentially()` 逐字输入(或直接用 `typeSlowly`) - 清空内容可用 `fill('')`,但填充内容必须逐字输入 - 示例选择器:`div.ql-editor`、`div[contenteditable="true"]` --- ## 交付 1. 确认录制报告 `ok=true`、文件非空。用 `video-edit frames` 抽帧,核对每个关键步骤、字幕、鼠标和首尾画面;从抽帧报告读取实际时长,与录制计划比对,分辨率以录制报告 `resolution` 为准: ```bash video-edit frames <project-dir>/output/demo.webm --interval 3 --width 1280 \ --output-dir <project-dir>/review/frames ``` 2. **原始录屏素材不直接运行 `video-review` 成片闸门**:内容区可能低于 720p,且默认无音轨,不能据此判定录制异常。需要进入成片流水线时,用 `video-edit` 按目标成片分辨率(如 1280x720 / 1920x1080)整理画布、按需求合成旁白/BGM,再运行 `video-review`;仅转为 MP4 不会补足分辨率或音轨。 3. 经微信等 IM 渠道交付时,先用 `video-edit extract` 将完整录屏转为 **MP4(H.264 + yuv420p + faststart)**,避免 WebM 上传/预览失败。`--keep-resolution` 保持录屏内容区尺寸,`--mode full` 由脚本自动读取时长并处理全片: ```bash video-edit extract --input <project-dir>/output/demo.webm --mode full \ --keep-resolution --no-audio --output <project-dir>/output/demo.mp4 ``` 转码后复查时长与关键帧。此 MP4 仍是无声录屏素材,适用上面的素材自检规则。 4. 按用户要求发送视频文件本体,附实际时长、分辨率与无音轨说明。拼接、配音、配乐等后处理走 `video-edit` 技能。 --- ## Checklist Before Recording - [ ] Phase 1 完成,每个页面字段映射已确认(CSS/text 选择器,不是 @ref) - [ ] Phase 2 完成:已问过用户是否旁观;全流程走通无报错 - [ ] 演习 session 的 `--headed` 一致性已检查;cookie 导出与 `close` 也使用原模式 - [ ] 录制计划(步骤+字幕+不录清单)已经用户确认 - [ ] 脚本选择器来自 Phase 1/2 的实际观察,无假设 - [ ] 所有点击使用 `moveAndClick`(含描述性 label) - [ ] 可见输入使用 `typeSlowly` - [ ] 滚动使用 `smoothScroll` - [ ] 关键过渡点有 `showSubtitle` - [ ] 需要登录态时 cookies.json 已从演习 session 导出 ## Common Pitfalls 1. 视频速度太快 → 增加停顿 2. Select placeholder 看起来非空 → Phase 1 时确认 value 是否为 `""` 或 `"0"` 3. 弹窗感觉突兀 → 确认前增加阅读停顿 4. **把 snapshot 的 `@ref` 写进 demo-steps** → ref 只在 camoufox-cli 会话内有效,脚本必须用 CSS/text 选择器 5. **富文本编辑器用 `fill()` 填充** → 必须用 `typeSlowly` / `pressSequentially()` 6. **混淆标题和正文输入框** → Phase 1 必须明确区分,标题和正文通常是独立的元素 7. SPA 路由切换后覆盖层丢失 → steps 里调 `injectOverlays()` 手动补 8. 演习完不 close session → daemon + Firefox 常驻吃内存,演习收尾必须 close 9. 有头 session 后续命令漏带 `--headed` → daemon 重启丢页面;所有命令直到 `close` 都保持一致 --- ## 浏览器操作最佳实践(Phase 1/2 探查演习时) ### 1. 超时与 session 正忙 - camoufox-cli 命令超时:**不要立即重启浏览器或放弃任务**。等待 30 秒后原 session 继续;仍失败再等 30 秒;60 秒后仍报错才 `close` 重开;重开后仍报错才停下反馈用户。 - 同一 session 的命令必须串行:等待上一条完成,再发下一条。返回 "session ui-demo 正忙" 时等待片刻重试,不要同时重试或切换 `--headed` 模式。 ### 2. 文件上传 演习中需要测试上传功能时:`camoufox-cli --session ui-demo --json upload @ref /path/to/file`。上传后用 `snapshot` 检查页面状态(进度条、缩略图、处理状态文字)确认结果,不要靠命令返回猜成败。 ### 3. 页面状态检查 - 操作后用 `snapshot` 检查关键元素是否存在、错误提示、URL 变化 - 找不到元素时先 `snapshot` 看真实 DOM 结构再改选择器,不要盲试
View on GitHub