1实现原理 · 为什么它能做到
产出物是「可录屏的伪装成网页的视频」:Vite + React + TS 项目 + 按章节切分的音频,HTML 验证通过后默认直接合成口播音频。
把一篇文章或口播稿,一步步做成可录屏的"伪装成网页的视频",HTML 验证完成后默认直接合成口播音频。产出物 = Vite + React + TS 项目 + 按章节切分的音频。
narrations.ts 是 step 数与音频合成的唯一真相源:章节代码里出现的最大 step + 1 必须等于 narrations.length。
> **关键**:`narrations.ts` 是 step 数和音频合成的**唯一真相源**。
硬性自检协议覆盖三个产出(script.md / outline.md / 单章实现),且要求先修 fail 项再汇报。
下面三个产出,每一个**完成后必须走自检 → 修复 → 再汇报 / 推进**:
outline 刻意不写动画:写死动画会让 chapter agent 退化为翻译机,留白才有真正的视频感。
> **outline 不写动画的理由**:写死动画 = chapter agent 退化为翻译机;
Checkpoint Plan 是硬节点:稿子、outline、素材、开发模式四件事一次对齐;主题默认 d2-editorial-grid。
## Checkpoint Plan —— 4 件事一次对齐(**硬节点**)
第 1 章强制主线程 + 用户验收:它是 CHAPTER-CRAFT 指引在当前主题/题材下的第一次落地,且是后续章节的代码风格锚点。
**第 1 章无论哪种模式都必须主线程做完 + 用户验收**(强制 anchor)。
Phase 3 默认不停下来问是否合成音频:HTML 全部完成且验证通过后直接进入音频合成,只在四种例外(用户说不要/鉴权缺失/要换本地 TTS)才收口。
**默认不要停下来问是否合成音频**。Phase 2 全部 HTML 已完成且验证通过后, agent 直接进入本阶段。
默认 TTS 配置写死为火山/豆包:engine=volcengine、seed-tts-2.0、voice_type zh_male_liufei_uranus_bigtts、speed 1.2、speech_rate 20。
engine=volcengine resource_id=seed-tts-2.0 voice_type=zh_male_liufei_uranus_bigtts voice_name=刘飞 2.0 speed=1.2 speech_rate=20
Phase 4 录屏默认走 CDP 自动录制,并明确拒绝用 screencli 跑本流程(会启动 AI agent、消耗 tokens)。
默认不要用 screencli 做本流程:它会启动 AI agent、消耗 tokens
视觉层面有十条一句话原则作为索引(16:9 固定舞台、全局 step 计数器、每步独占整屏、口播节拍=step、内容驱动动画、逐步揭示、双源原则等)。
| 10 | 双源原则 | script 定节拍,**article 定画面密度**(落到信息池) |
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | npm / Vite 脚手架与依赖安装(npm create vite、npm install、npm install --save-dev tsx puppeteer-core、npx tsc --noEmit) |
| api | 火山/豆包语音合成(默认引擎;鉴权仅从环境变量读,curl 调 unidirectional 接口) |
| api | MiniMax CLI(可选 TTS 路径,走 mmx auth login --api-key;key 在平台获取) |
| cli | MeloTTS 本地路径(可选:调 ../../.venv-tts/bin/melotts 生成 wav 再用 ffmpeg 转 mp3) |
| package | puppeteer-core + 本机 Chrome(CDP 录屏与字幕烧录;headless 启动参数不含任何反自动化绕过) |
| network | Google Fonts(主题 CSS 引用,浏览器端/录屏期拉取)与本地 dev server 端口 |
4风险提醒 风险提醒:橙色 · 评估后使用
- 默认无二次确认地调用付费 TTS,且会读本机凭证文件 — synthesize-audio.sh 在 env 缺失时 source $HOME/.config/doubao-tts/env;文档又明确「默认不要停下来问是否合成音频」。使用前应确认额度与是否允许把稿件逐段发给火山/豆包(见 second_pass 的 discrepancy 条)。
- 分章节并行开发造成风格分散 — 模式 C 下每个 subagent 看不到彼此产出,文档承认风格会有差异(靠主题 token 兜底);若项目要求高度统一,应改用模式 A/B 或人工统一关键视觉。
- 稿件与原文内容直接进入生成上下文与 subagent prompt — article.md / outline 信息池 / 第 1 章代码都会拼进 subagent prompt;若素材含指令式文本,理论上可影响章节实现(本 skill 未提供消毒/隔离条款)。
- 主题与字体资产带第三方依赖 — themes 与 fonts.css 通过 @import 引 Google Fonts(浏览器/录屏期拉取,执行期不外发);商用发布需自行核对字体许可。
- 录屏依赖本机 Chrome 与 ffmpeg,平台假设偏 macOS — record-cdp-screencast.mjs 默认 chromePath 指向 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome,其他平台需用 --chrome 覆盖;Windows/Linux 使用者需自行改路径。
- 流程文档很长,长会话易漂移 — 文档自身承认「长会话里 agent 容易遗忘原则」,要求在每次实现单章前重读 CHAPTER-CRAFT.md;缺失这一步会退化成模板堆砌。
5第二遍独立确认
- [ok] TTS 凭证读取与外发是否真实(橙档关键证据) — synthesize-audio.sh 原文:'# 2. DOUBAO_TTS_API_KEY or VOLCENGINE_TTS_API_KEY for default Volcengine/Doubao TTS';'DEFAULT_VOLCENGINE_ENV_FILE="$HOME/.config/doubao-tts/env"';缺失时 source 该文件;取到后作为鉴权头 curl 到 https://openspeech.bytedance.com/api/v3/tts/unidirectional。调用点与降级说明(AUDIO.md 的「缺少 API Key 时不要假装合成成功」)一致。
- [ok] 是否存在反自动化绕过或安全降级(红档排除) — record-cdp-screencast.mjs 的 puppeteer.launch 只有 headless: true 与 args=[--autoplay-policy=no-user-gesture-required, --hide-scrollbars, --window-size=…],无 AutomationControlled、无 remote-allow-origins=*、无 webdriver 伪装;全目录 grep --no-verify / --sandbox / dangerouslyDisableSandbox 零命中。CDP 只连本机回环页面(默认 http://127.0.0.1:5175/?auto=1&record=1&autostart=1)。
- [discrepancy] 「默认不停下问」会不会导致未经同意的付费合成 — [判定:设计取舍,非缺陷]SKILL.md 明写 '**默认不要停下来问是否合成音频**。Phase 2 全部 HTML 已完成且验证通过后,agent 直接进入本阶段。',并列出四种收口例外(用户说不要/鉴权缺失/换本地 TTS)。即:默认路径会消耗 TTS 账号额度且不再二次确认——属有意的流程设计(音频是一镜到底前提),但使用者应在开始前知情并配好额度与凭证。
- [ok] 脚手架是否真的安装 puppeteer-core(录屏能力来源) — scripts/scaffold.sh 内含 `npm install >/dev/null 2>&1` 与 `npm install --save-dev tsx puppeteer-core >/dev/null 2>&1`,随后跑 `npx tsc --noEmit` 自检;即录屏/字幕脚本的依赖由脚手架负责安装,而非假定全局存在。
- [unlocatable] 并行章节开发(模式 C)带来的风格与质量分散 — 文档声称主题 token 兜底、章节 CSS 物理隔离、风格不一致等于「人手写视频的呼吸感」;但 pin 仓库内没有多章并行产出的成品或验收记录可用于验证该主张,本次只读侦查不运行生成,故仅作「文档声明」记录,不当作已核事实。
- [ok] 「?auto=1 一镜到底」的机制描述是否与代码一致 — AUDIO.md 与 build-master-audio.mjs 的描述一致:分段合成后拼成 master.mp3 + timeline.json,运行时 Auto 模式优先播 master 音轨并按 timeline 驱动 HTML 节点;RECORDING.md 的 CDP 路径以 --audio=<normalized master> 复用同一条母版,避免分段交接造成尾字截断。
6结论
6c6b9cedf0142114…f2c70b812b