mcpField
V
video-docs-builder

video-docs-builder

github.com/tecnomanu创意与媒体2440 次安装4 周前更新
代码仓库

关于 video-docs-builder

video-docs-builder 是用于网页应用交互式文档视频的 Agent 技能,面向需要录制产品操作说明的团队。它串联 Playwright 录屏、TTS 旁白、FFmpeg 合成和 React 文档站点生成,并支持多语言流程。

主要功能

  1. 01Playwright 浏览器录制与应用分析
  2. 02通过 TTS 生成旁白
  3. 03FFmpeg 合成视频
  4. 04生成 React 文档站点
  5. 05按语言管理流程和输出

适用场景

  1. 01录制登录与仪表盘操作说明
  2. 02为多个界面章节制作文档视频
  3. 03生成不同语言的旁白视频

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tecnomanu/video-docs-builder --skill video-docs-builder

安装后在 Claude Code 中输入/video-docs-builder确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
.env.example
TTS-PROVIDERS.md
TROUBLESHOOTING.md
README.md
LICENSE
package.json
package-lock.json
evaluations/
eval-03-docs-site.json
eval-01-document-login.json
eval-02-existing-project.json
scripts/
gen-all-flows.sh
adjust-timing.ts
generate-audio.ts
analyze-app.ts
assemble.ts
generate-docs-site.ts
paths.ts
run-all.sh
generate-video.ts
rehearse.ts
init-project.ts
setup.sh
types.ts
tools/piper-tts/
.env.example
.gitignore
README.md
package.json
tools/piper-tts/src/
generate.ts
tools/piper-tts/voices/
.gitkeep

详细介绍

视频文档构建器

为 Web 应用录制交互式文档视频。

流程:Playwright(浏览器录制)→ TTS 旁白 → FFmpeg 组装 → React 文档站点

技能根目录:包含此 SKILL.md 文件的目录。所有命令都从这里运行。


目录


技能结构

video-docs-builder/
├── SKILL.md                      ← Agent instructions (this file)
├── TTS-PROVIDERS.md              ← TTS provider setup and voice options
├── TROUBLESHOOTING.md            ← Common errors and fixes
├── evaluations/                  ← Test scenarios
├── package.json
├── scripts/
│   ├── setup.sh                  ← Runs first time to install deps + configure TTS
│   ├── run-all.sh                ← Full pipeline for one flow
│   ├── gen-all-flows.sh          ← Batch pipeline for a flows directory
│   ├── analyze-app.ts            ← Playwright: discovers sections, screenshots
│   ├── generate-audio.ts         ← TTS: generates MP3 per step
│   ├── generate-video.ts         ← Playwright: records video with cursor
│   ├── assemble.ts               ← FFmpeg: assembles final MP4
│   ├── adjust-timing.ts          ← Adjust audio timing without re-recording
│   ├── generate-docs-site.ts     ← Generates React docs site from videos
│   └── types.ts                  ← Shared TypeScript types
├── tools/
│   └── piper-tts/                ← Free local TTS (language-specific voice models)
└── projects/                     ← gitignored — legacy location (still supported)

首次设置

开始前务必确认技能已就绪:

# 1. Check .env exists and TTS is configured
ls .env 2>/dev/null && grep '^TTS_PROVIDER' .env || echo "NO .env — run scripts/setup.sh"

如果缺少 .env 或未设置 TTS_PROVIDER → 停止并运行设置程序:

bash scripts/setup.sh

向导会安装 npm 依赖、安装 Playwright Chromium、检查 FFmpeg,并询问要配置哪个 TTS 提供商:

Which TTS provider?
  A) Piper (free, local — included in tools/piper-tts/)
  B) ElevenLabs (best quality — API key required)
  C) OpenAI TTS (very good — API key required)
  D) Google Gemini TTS (very natural — GEMINI_API_KEY required)

**不要跳过此步骤。**没有 .env,音频生成将会失败。

保持技能为最新版本

该技能通过 git clone 安装。开始会话前,请拉取最新版本:

git pull

TTS 提供商

提供商质量费用语言
Piper良好免费特定语言的语音模型(参见 TTS-PROVIDERS.md)
ElevenLabs卓越免费层级 / 付费多语言——支持任何语言,无需额外配置
OpenAI TTS很好付费 API多语言——支持任何语言,无需额外配置
Google Gemini卓越免费层级(AI Studio)多语言——建议西班牙语使用 Kore 语音

完整的设置说明、各语言的语音模型以及环境变量,请参见 TTS-PROVIDERS.md。


旁白语言

旁白语言绝不硬编码——始终根据上下文推断:

  1. 用户的语言——如果用户用西班牙语书写,就用西班牙语配旁白;如果用英语,就用英语;如果用俄语,就用俄语。
  2. 应用界面语言——如果应用界面语言与用户所用语言不同,请询问应使用哪种语言:
    应用界面似乎是英语,但您用西班牙语与我交流。
    旁白应使用哪种语言?
      A) 西班牙语(与我们的对话语言相同)
      B) 英语(与应用界面语言相同)
    
  3. 不确定时——编写任何 flow JSON 前先询问。

TTS 提供商兼容性:

  • ElevenLabs / OpenAI TTS——支持多语言,可自动用于任何语言。
  • Piper——需要指定语言的语音模型。查看 TTS-PROVIDERS.md 了解可用语音。如果目标语言没有对应语音,请建议切换到 ElevenLabs 或 OpenAI TTS。

多语言视频

要以多种语言制作相同的流程,请将 flow JSON 放在语言子目录中:

flows/
├── es/01-login.json    ← Spanish narration
├── en/01-login.json    ← English narration
└── pt/01-login.json    ← Portuguese narration

语言会自动检测——流程会从文件夹名称读取语言代码,并使用 .env 中对应的语音。每种语言的输出会分别保存在 output/<lang>/ 下。

.env 中的各语言语音
# ── Default voice (used when no language-specific voice is set) ───────────────
ELEVENLABS_VOICE_ID=EXAVITQu4vr4xnSDxMaL
OPENAI_VOICE=nova
PIPER_VOICE=es_AR-daniela-high

# ── Per-language overrides (optional — fall back to default if not set) ───────
ELEVENLABS_VOICE_ES_ID=<elevenlabs-id-for-spanish>
ELEVENLABS_VOICE_EN_ID=<elevenlabs-id-for-english>
ELEVENLABS_VOICE_PT_ID=<elevenlabs-id-for-portuguese>

OPENAI_VOICE_ES=nova
OPENAI_VOICE_EN=alloy
OPENAI_VOICE_PT=shimmer

PIPER_VOICE_ES=es_AR-daniela-high
PIPER_VOICE_EN=en_US-lessac-medium

优先级顺序:ELEVENLABS_VOICE_{LANG}_ID → ELEVENLABS_VOICE_ID(OpenAI 和 Piper 也遵循相同模式)。

运行多语言流程
# Run Spanish flow
bash scripts/run-all.sh /abs/path/client/.video-docs/flows/es/01-login.json
# → output goes to .video-docs/output/es/01-login/final/

# Run English flow
bash scripts/run-all.sh /abs/path/client/.video-docs/flows/en/01-login.json
# → output goes to .video-docs/output/en/01-login/final/
多语言工作流——优先处理主要语言

始终先完成主要语言,再开始处理其他语言。

首次运行时会发现流程中的错误(选择器错误、时序问题、旁白调整)。先在一种语言中修复,再复制到其他语言,远比并行处理多种语言时逐一修复相同问题省时。

用户要求使用多种语言时的流程:

  1. 确定主要语言(通常是用户使用的语言或应用的主要区域设置)。
  2. 完成该语言的整个流程:流程 → 音频 → 视频 → 组装。
  3. 展示结果并请求确认:
✅ Primary language (ES) done — 3 videos generated.

Before I continue with EN and PT, please review:
  • .video-docs/output/es/01-login/final/01-login.mp4
  • .video-docs/output/es/02-dashboard/final/02-dashboard.mp4
  • .video-docs/output/es/03-settings/final/03-settings.mp4

Does everything look good? (narration, timing, UI interactions)
  A) Yes, continue with EN and PT
  B) Fix [describe issue] first, then continue
  1. 仅在客户端确认后,才继续处理剩余语言。

这样可以避免每次调整旁白或修复选择器时,都为 N 种语言重新生成音频和视频。


项目存储——文件所在位置

项目存储在客户端自己的仓库中,而非技能内部:

client-project/                    ← client's Git repository
├── .gitignore                     ← skill adds: .video-docs/output/
└── .video-docs/                   ← all video-docs files live here
    ├── README.md                  ← regeneration instructions (commit this)
    ├── config.json                ← app URL + credentials (add to .gitignore if sensitive)
    ├── flows/                     ← flow JSONs — commit these, they're small and useful
    │   ├── 01-login.json          ← no language (default)
    │   ├── es/                    ← Spanish flows (optional)
    │   │   └── 01-login.json
    │   └── en/                    ← English flows (optional)
    │       └── 01-login.json
    ├── output/                    ← gitignored — heavy generated files
    │   ├── .gitignore
    │   ├── 01-login/              ← output for default (no language) flows
    │   │   ├── audio/
    │   │   ├── raw/
    │   │   └── final/             ← 01-login.mp4
    │   ├── es/                    ← output for Spanish flows
    │   │   └── 01-login/
    │   │       └── final/         ← 01-login.mp4
    │   └── en/
    │       └── 01-login/
    │           └── final/         ← 01-login.mp4
    └── docs/                      ← React docs site — commit or ignore (your choice)

语言会自动检测——如果流程位于 flows/es/ 下,输出就会写入 output/es/。无需额外标志。

采用此结构的原因:

  • flows/ 可进行版本控制——每种语言都有自己的旁白脚本
  • output/ 已被 gitignore——随时可以根据流程重新生成任意语言
  • 向后兼容——直接放在 flows/ 中(没有语言子目录)的流程仍可按原样正常运行
初始化新项目
npm run init-project /absolute/path/to/client-project
# Creates .video-docs/ structure and adds .video-docs/output/ to .gitignore
所有命令都使用绝对路径
# From the skill directory:
bash scripts/run-all.sh /absolute/path/client/.video-docs/flows/01-login.json
bash scripts/run-all.sh /absolute/path/client/.video-docs/flows/es/01-login.json
npx tsx scripts/generate-docs-site.ts /absolute/path/client/.video-docs --dev
npx tsx scripts/analyze-app.ts /absolute/path/client/.video-docs

交互流程

按顺序执行以下步骤。复制下面的检查清单并跟踪进度。

Documentation Progress:
- [ ] Step 0: Verify setup (.env exists, TTS configured, git pull)
- [ ] Step 1: Get app info (URL, client project path, credentials)
- [ ] Step 2: Initialize .video-docs/ in client project (npm run init-project)
- [ ] Step 3: Analyze the app (npx tsx scripts/analyze-app.ts <path>)
- [ ] Step 4: Choose sections to document
- [ ] Step 5: Create or update flow JSONs
- [ ] Step 5b: Rehearse the flow (npx tsx scripts/rehearse.ts <flow.json>)
- [ ] Step 6: Confirm TTS provider
- [ ] Step 7: Run the pipeline (absolute path to flow)
- [ ] Step 8: Generate docs site (optional)

步骤 1——获取应用信息

询问用户:

Which app do you want to document?
  • Base URL (e.g. http://localhost:8100)
  • Absolute path to the client project (e.g. /home/user/projects/my-app)
• Access credentials: email and password
  (or let me know if .video-docs/config.json already exists in that project)

步骤 2——在客户端项目中初始化 .video-docs/

检查 .video-docs/ 是否已存在:

ls /absolute/path/client/.video-docs/config.json 2>/dev/null && echo "exists" || echo "missing"

如果不存在 → 初始化:

npm run init-project /absolute/path/to/client-project

然后使用实际应用信息编辑 .video-docs/config.json:

{
	"app_name": "<visible app name>",
	"base_url": "<URL>",
	"credentials": {
		"demo": { "email": "<email>", "password": "<password>" }
	},
	"setup_login": { "email": "<email>", "password": "<password>" }
}

步骤 3——分析应用
npx tsx scripts/analyze-app.ts /absolute/path/client/.video-docs

浏览应用,为每个导航栏分区截图,提取 CSS 选择器,并保存到:

  • .video-docs/analysis/sections.json
  • .video-docs/analysis/screenshots/

如果自动登录失败:在命令中添加 -- --no-login。

SPA 注意事项:如果应用使用 Vite/Webpack 开发服务器,请确保生产构建处于活动状态(不存在 public/hot 文件)。请参阅 TROUBLESHOOTING.md。


步骤 4——选择要编写文档的分区

按字母列表展示发现的分区:

Found these sections in [App Name]:

  A) Login              — /login
  B) Dashboard          — /dashboard  [existing flow: 01-dashboard.json]
  C) Bot Management     — /bots
  D) All sections

Which sections to document? (e.g. A, C or D for all)

步骤 5——创建或复用流程 JSON

如果流程已存在:

"[Section]" already has a flow: /absolute/path/client/.video-docs/flows/<name>.json

  A) Use existing flow as-is
  B) Update flow based on current screenshots
  C) Create from scratch

如果没有流程 → 直接编写。查看 .video-docs/analysis/screenshots/ 中的截图以了解界面。

流程 JSON 模板:

{
	"project": "<name>",
	"title": "<descriptive title>",
	"category": "<docs site sidebar group, e.g. Getting Started>",
	"description": "<one-line summary shown in docs site cards>",
	"steps_summary": ["Step 1 text", "Step 2 text"],
	"output_name": "<NN-slug>",
	"viewport": { "width": 1280, "height": 800 },
	"use_setup_login": true,
	"steps": [
		{
			"id": "navigate_section",
			"action": "navigate",
			"value": "<URL>",
			"narration": "<What this screen is and what the user can do here>",
			"action_ms": 2000,
			"wait_for": "<CSS selector confirming the page has rendered>"
		},
		{
			"id": "pre_action",
			"action": "wait",
			"narration": "<Narrate WHAT WE ARE ABOUT TO DO — plays BEFORE the action>",
			"action_ms": 600
		},
		{
			"id": "do_action",
			"action": "click",
			"selector": "<CSS selector>",
			"action_ms": 500
		}
	]
}

action_ms 指南:

  • navigate SPA:2000ms + wait_for: "<selector confirming render>"
  • fill:600–800ms(无需旁白——静音输入会显得自然)
  • 简单的 click:800ms
  • 会触发导航的 click:500ms + wait_for_url
  • 用于显示内容的 wait:2000–3000ms

use_setup_login:

  • false → 视频会展示登录过程(流程内容就是登录)
  • true → 在开始录制前,登录过程会在镜头外完成

步骤 5b——排练流程

运行完整流程前,务必先进行排练。

排练会使用 Playwright 执行所有步骤(真实浏览器、真实选择器、真实导航),但会跳过视频录制、音频生成和旁白停顿。整个过程只需几秒,并会一次性报告所有失败步骤,而不是在 TTS 运行数分钟后于流程中途失败。

npx tsx scripts/rehearse.ts /abs/path/client/.video-docs/flows/<flow>.json

输出示例:

🎭 Rehearsing: "Checkout flow"
   8 steps + 4 setup

🔐 Setup login ([email protected])... ✅ → /dashboard
📋 Setup steps:
   setup[0] navigate → https://app/plans... ✅
   setup[1] click .plan-card button... ✅

📹 Recording steps:
   [navigate_checkout] navigate → https://app/checkout... ✅ 312ms → /checkout
   [fill_email] fill #email → [email protected]... ✅ 98ms
   [fill_card] fill #card-number → 4242... ❌ Timeout: waiting for #card-number
   [submit] click button[type=submit]... ❌ Timeout: waiting for button[type=submit]

─────────────────────────────────────────────────
🎭 Rehearsal complete: 6/8 steps passed (2.4s)

❌ Failed steps (2):
   • [fill_card] Timeout: waiting for #card-number
   • [submit] Timeout: waiting for button[type=submit]

⚠️  Fix these steps before running the full pipeline.

修复报告中的选择器,然后重复排练,直到所有步骤都通过,再启动 run-all.sh。

排练中的 mailpit_code——注入虚拟代码 "123456",避免下游使用 ${variable} 的 fill 步骤因缺少代码而失败。此操作仅验证 OTP 输入框是否存在且能接受输入,不会测试实际邮件投递。


步骤 6——确认 TTS 提供商
grep '^TTS_PROVIDER' .env

如果尚未配置 → 询问:

Which TTS provider should I use?
  A) Piper (free, local — included in tools/piper-tts/)
  B) ElevenLabs (best quality — API key required)
  C) OpenAI TTS (very good — API key required)
  D) Google Gemini TTS (very natural — GEMINI_API_KEY required)

有关设置详情 → 请参阅 TTS-PROVIDERS.md。


STEP 7 — 运行工作流

始终使用工作流文件的绝对路径:

bash scripts/run-all.sh /absolute/path/client/.video-docs/flows/<flow>.json

标志:

  • --skip-audio → 仅重新录制视频(UI 已更改,保留音频)
  • --skip-video → 仅重新组装(调整时间)

如果出现错误 → 请参阅 TROUBLESHOOTING.md。


STEP 8 — 生成文档网站(可选)
Videos are ready! 🎉

Would you like a React docs site with all videos embedded?
  A) No, just the videos
  B) Yes, generate site — opens browser automatically
  C) Yes, add videos to an existing docs site (tell me the path)

选项 B:

npx tsx scripts/generate-docs-site.ts /absolute/path/client/.video-docs
# Generates .video-docs/docs/, installs deps, opens browser automatically
# Add --no-open to skip auto-launch

选项 C:

npx tsx scripts/generate-docs-site.ts /absolute/path/client/.video-docs --existing <path>

Flow JSON 格式

两阶段执行模型

每个 flow 都有两个阶段。最终视频中只会出现第 2 阶段。

Phase 1 — Setup (off-camera, trimmed away)
  use_setup_login: true  → automatic login from config.json credentials
  setup: [...]           → any custom Playwright steps (navigate, click, fill, wait_ms)

Phase 2 — Recording (what the viewer sees)
  steps: [...]           → narrated, timed tutorial steps

当视频需要从工作流中途开始时,请使用 setup[]——例如,已登录、已打开特定页面、购物车已填充、已输入 OTP 等。 观众不会看到这些步骤。


Flow JSON — 完整参考
{
  "project": "<name>",
  "title": "<descriptive title>",
  "category": "<docs site sidebar group, e.g. Getting Started>",
  "description": "<one-line summary shown in docs site cards>",
  "steps_summary": ["Step 1 text", "Step 2 text"],
  "output_name": "<NN-slug>",
  "viewport": { "width": 1280, "height": 800 },

  "use_setup_login": true,
  "show_cursor": true,
  "setup": [
    { "action": "navigate", "value": "https://app.example.com/plans" },
    { "action": "click",    "selector": ".plan-card:first-child button" },
    { "action": "wait_ms",  "value": "1500" },
    { "action": "fill",     "selector": "#email", "value": "[email protected]" }
  ],

  "steps": [
    {
      "id": "navigate_checkout",
      "action": "navigate",
      "value": "https://app.example.com/checkout",
      "narration": "We are now at the checkout screen.",
      "action_ms": 2000,
      "wait_for": ".checkout-form"
    },
    {
      "id": "pre_click",
      "action": "wait",
      "narration": "We fill in the card number and confirm.",
      "action_ms": 600
    },
    {
      "id": "fill_card",
      "action": "fill",
      "selector": "#card-number",
      "value": "4242 4242 4242 4242",
      "action_ms": 800
    },
    {
      "id": "submit",
      "action": "click",
      "selector": "button[type=submit]",
      "action_ms": 500,
      "wait_for_url": "/confirmation"
    }
  ]
}

use_setup_login

  • false(或省略)→ 视频会显示登录过程——当 flow 本身就是关于登录时使用
  • true → 录制前使用 config.setup_login 在镜头外静默登录

show_cursor(默认值为 true)

  • true → 显示红点光标叠加层——大多数 flow 推荐使用
  • false → 隐藏光标——适用于红点会分散注意力的表单较多的 flow,或不需要展示指针移动的 flow

setup[] — 在录制前运行,不会出现在视频中。支持:

actionfieldsdescription
navigatevalue:URL跳转到某个 URL
fillselector、value填写字段
clickselector点击元素
wait_msvalue:毫秒字符串等待 N 毫秒

步骤字段(steps[])

fieldtypedescription
idstring唯一标识符(用于音频文件名)
actionstring参见下方的操作表
valuestringURL / 文本 / 变量名 — 支持 ${varName} 替换
selectorCSS目标元素
nthnumber选择器匹配多个元素时使用的从 0 开始的索引
narrationstringTTS 朗读的文本 — 静默步骤可省略
action_msnumber操作后、下一步开始前的暂停时长
wait_forCSS操作后等待此选择器对应的元素出现
wait_for_urlstring操作后等待 URL 包含此片段
emailstring用于 mailpit_code — 要搜索的电子邮件地址(覆盖默认值)
可用操作(steps[])
actionvalueselector说明
navigateURL—导航到 URL
fill文本或 ${var}CSS填写输入框 — 即时完成,不触发键盘事件
type文本或 ${var}CSS逐字符输入(200ms/字符)— 当 fill 无法触发验证或处理掩码字段时使用
click—CSS点击元素
blur—CSS移除焦点(按 Tab)— 在 type 后触发失焦验证时很有用
paste文本或 ${var}CSS派发 ClipboardEvent — 适用于监听 onPaste 且忽略 fill 的 React 输入框
otp_fill验证码或 ${var}CSS(可选)逐位填写多输入框 OTP 组件(默认选择器:input[inputmode="numeric"])
hover—CSS将光标移到元素上(用于工具提示、下拉菜单)
scroll"down" | "up" | pxCSS(可选)滚动页面或元素进入视野
wait——暂停 action_ms 毫秒 — 用于旁白窗口
mailpit_code变量名称—仅限 Mailpit — 提取 6 位 OTP 并存入变量
变量替换

在 value 字段的任意位置使用 ${varName},即可注入已存储的变量:

{ "id": "get_otp",  "action": "mailpit_code", "value": "otp", "email": "[email protected]", "action_ms": 1000 },
{ "id": "fill_otp", "action": "fill", "selector": "#otp-input", "value": "${otp}", "action_ms": 600 }
常见的录制前操作模式

在需要先经过多个页面才能到达的页面开始视频:

"use_setup_login": true,
"setup": [
  { "action": "navigate", "value": "https://app/products" },
  { "action": "click",    "selector": ".product-card:first-child a" },
  { "action": "wait_ms",  "value": "1200" },
  { "action": "click",    "selector": "button.add-to-cart" },
  { "action": "navigate", "value": "https://app/checkout" },
  { "action": "wait_ms",  "value": "1000" }
]

在镜头外注册新用户(视频在账户创建后开始):

"use_setup_login": false,
"setup": [
  { "action": "navigate", "value": "https://app/register" },
  { "action": "fill",     "selector": "#email",    "value": "[email protected]" },
  { "action": "fill",     "selector": "#password", "value": "Demo1234!" },
  { "action": "click",    "selector": "button[type=submit]" },
  { "action": "wait_ms",  "value": "2000" }
]
邮箱 / OTP 验证流程

编写 OTP 流程前,务必先询问客户端:

Does the flow involve an email verification code or OTP?
If yes — how does your test environment handle email?
  A) Mailpit (local inbox at localhost:8025 or similar)
  B) Mailtrap or another SMTP testing service
  C) The code arrives to a real inbox I can read manually
  D) No email verification involved

每个选项都需要采用不同的方法:

A)Mailpit — 使用内置的 mailpit_code 操作。确保在 config.json 中设置了 mailpit_url:

// config.json
{ "mailpit_url": "http://localhost:8025" }
// flow setup[] + steps[]
"setup": [
  { "action": "click",   "selector": "#send-otp-button" },
  { "action": "wait_ms", "value": "2000" }
],
"steps": [
  { "id": "get_code",  "action": "mailpit_code", "value": "otp", "email": "[email protected]", "action_ms": 500 },
  { "id": "fill_code", "action": "fill", "selector": "#otp-input", "value": "${otp}", "action_ms": 600 },
  { "id": "submit",    "action": "click", "selector": "button[type=submit]", "action_ms": 500, "wait_for_url": "/dashboard" }
]

B)Mailtrap / 外部服务 — mailpit_code 不起作用。如果测试账户始终收到相同的验证码,请使用固定的演示验证码;或者在 setup[] 中使用预先验证过的账户,在演示中跳过 OTP:

"setup": [
  { "action": "navigate", "value": "https://app/register" },
  { "action": "fill",     "selector": "#email",    "value": "[email protected]" },
  { "action": "fill",     "selector": "#password", "value": "Demo1234!" },
  { "action": "click",    "selector": "button[type=submit]" },
  { "action": "wait_ms",  "value": "2000" }
]

C)手动验证码 — 请客户端先手动运行流程并记下验证码,然后将其硬编码为 fill 值。或者使用可完全跳过 OTP 的预验证测试账户。

mailpit_code 仅在 steps[] 中可用,不能用于 setup[]。如需在不显示验证过程的情况下处理 OTP,可在 setup[] 中触发发送,并在第一个录制步骤中提取验证码 — 提取速度很快,观众只会看到短暂停顿。


时序黄金法则

旁白描述的是即将发生的事情,而不是刚刚发生的事情。

❌ Wrong — dashboard appears 4s before narration
{ "id": "click_login", "action": "click", ..., "narration": "We click Login", "action_ms": 4000 }

✅ Right — narration plays on the form, THEN click happens
{ "id": "pre_login",  "action": "wait",  "narration": "We click Login to authenticate.", "action_ms": 600 },
{ "id": "click_login","action": "click", ..., "action_ms": 500, "wait_for_url": "/dashboard" }

快速命令参考

# Analyze app and discover sections
npx tsx scripts/analyze-app.ts /absolute/path/client/.video-docs
npx tsx scripts/analyze-app.ts /absolute/path/client/.video-docs --no-login

# Rehearse a flow (validate selectors without recording)
npx tsx scripts/rehearse.ts /absolute/path/client/.video-docs/flows/<flow>.json

# Full pipeline for one flow
bash scripts/run-all.sh /absolute/path/client/.video-docs/flows/<flow>.json

# Individual steps
npx tsx scripts/generate-audio.ts /absolute/path/client/.video-docs/flows/<flow>.json
npx tsx scripts/generate-video.ts /absolute/path/client/.video-docs/flows/<flow>.json
npx tsx scripts/assemble.ts /absolute/path/client/.video-docs/flows/<flow>.enriched.json

# Re-record without regenerating audio
bash scripts/run-all.sh /absolute/path/client/.video-docs/flows/<flow>.json --skip-audio

# Adjust audio timing without re-recording
npx tsx scripts/adjust-timing.ts /absolute/path/client/.video-docs/flows/<flow>.enriched.json --show
npx tsx scripts/adjust-timing.ts ... --step <id>:<ms> --reassemble

# Batch all flows in a directory
bash scripts/gen-all-flows.sh /absolute/path/client/.video-docs/flows/

# Generate docs site (with auto browser open)
npx tsx scripts/generate-docs-site.ts /absolute/path/client/.video-docs --dev
npx tsx scripts/generate-docs-site.ts /absolute/path/client/.video-docs --out /custom/path
npx tsx scripts/generate-docs-site.ts /absolute/path/client/.video-docs --existing /path/to/existing/docs

输出结构

/absolute/path/client/.video-docs/
├── output/
│   └── <flow-name>/
│       ├── audio/           ← MP3 per step
│       ├── raw/             ← .webm recording
│       └── final/
│           ├── <flow>.mp4   ← FINAL VIDEO
│           └── <flow>-thumb.jpg
└── docs/                    ← React site (if generated)
    ├── package.json
    ├── src/App.tsx
    └── public/videos/

评论

支持 Markdown