diff --git a/.claude/skills/video-from-script/SKILL.md b/.claude/skills/video-from-script/SKILL.md index af08b6e..494528a 100644 --- a/.claude/skills/video-from-script/SKILL.md +++ b/.claude/skills/video-from-script/SKILL.md @@ -110,12 +110,11 @@ Step 0: 前置检查(账号+风格校验) - 校验账号完整性:`pipeline.js validate-account --account ` - 有风格则继续 Step 1 -Step 1: 分镜规划(纯叙事,不读风格) - - 输入:用户文案 - - 分析文案语义和节奏,拆成 N 个 shot - - 为每个 shot 规划:景别、镜头运动、画面内容(中文)、与下一 shot 的转场 - - 输出分镜表(见「分镜规划规则」章节) - - 分镜与风格无关,同一分镜可换不同风格复用 +Step 1: 分镜规划(子 Agent 执行) + - 主 Agent 将用户文案 + 约束交给子 Agent + - 子 Agent 读取 references/storyboard-rules.md,按要求输出分镜表 + - 主 Agent 审查分镜表(景别交替、hook 设置、时长合理) + - 展示给用户确认,确认后进入 Step 2 Step 2: Prompt 生成 + Manifest 初始化(分镜 + 风格 → 英文 prompts → pipeline.js init) - 输入:分镜表 + style.md + account.json @@ -393,105 +392,13 @@ output/{account}_{YYYYMMDD}_{NNN}/ ## 分镜规划规则 -**分镜是 Agent 的纯叙事思考,与视觉风格无关。** 拿到文案后、读风格文件之前,先完成分镜。 - -短视频的画面节奏和文案节奏是脱钩的:TTS 配音连续流淌,画面在配音下面切换。分镜规划的是**视觉节拍**,不是文字断句。 - -### 核心原则 - -1. **按视觉节拍切 shot**:每个 shot = 6-8 秒视频片段。不是按文字断句,而是按画面能承载的信息量切 -2. **前 3 秒 hook**:shot 1 必须有强视觉冲击,决定完播率 -3. **景别快速交替**:相邻 shot 景别必须有落差(wide → close-up,close-up → medium),不要连续同一景别 -4. **镜头服务情绪**:每个 cameraMove 对应文案的情绪节拍,不要无意义运动 -5. **时长匹配**:先算总时长(shot 数 × 6-8s),再和配音时长对齐 - -### 时长规划 - -分镜前先算数: -- 短视频目标时长:20-60 秒 -- 每个 shot 时长:6-8 秒(由视频模型决定) -- shot 数量 = 目标时长 ÷ 6~8(取整,一般 4-8 个 shot) -- 配音字数 ≈ shot 数 × 12-15 字(按正常语速) - -### 分镜表字段 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `text` | string | 该 shot 覆盖的配音文案(可能不到一句,也可能跨句) | -| `shotType` | enum | `wide` / `medium` / `close-up` / `extreme-close-up` | -| `cameraMove` | enum | `static` / `zoom-in` / `zoom-out` / `pan-left` / `pan-right` / `dolly-in` / `tracking` | -| `visualDesc` | string | 画面描述(中文),只写三件事:**主体是什么、什么状态/动作、视觉焦点在哪**。氛围和构图交给风格层 | -| `hook` | boolean | 仅 shot 1 为 true,标记是否为开场钩子 | - -### 景别节奏 - -``` -shot 1 (hook): close-up 或 extreme-close-up,强主体,抓眼球 -shot 2: wide 或 medium,展开场景,给上下文 -shot 3-N(交替): close-up(压)→ wide(松)→ close-up(压)→ ... -最后一个 shot: medium 或 wide,收束,不过度设计 -``` - -不要用 extreme-close-up 收尾(太紧),不要用 tracking 滥用(信息密度低)。 - -### 镜头运动选择 - -| cameraMove | 情绪 | 典型场景 | -|------------|------|---------| -| `static` | 稳定、庄严 | 建筑、静物、仪式感 | -| `zoom-in` | 聚焦、压迫 | 悬疑、揭秘、强调细节 | -| `zoom-out` | 揭示、震撼 | 从局部拉出全景,揭示真相 | -| `pan-left/right` | 环顾、流动 | 展示空间、物品陈列 | -| `dolly-in` | 沉浸、紧张 | 人物面部、关键物件 | -| `tracking` | 跟随、活力 | 运动场景、行走(少用,AI 生成的 tracking 质量不稳定) | - -短视频默认转场是硬切,不需要单独字段。特殊转场(fade/dissolve)仅在 Agent 判断需要情绪转换时标注在 `visualDesc` 里。 +完整规则见 [storyboard-rules.md](references/storyboard-rules.md)。由子 Agent 读取并执行,主 Agent 只审查输出。 --- ## 提示词生成规则 -**提示词由子 Agent 生成**:主 Agent 将分镜表 + 风格文件(style.md)交给子 Agent,子 Agent 负责将中文画面描述转化为英文 imagePrompt / videoPrompt。主 Agent 审核提示词质量,不合格则退回重做。 - -**前置条件**:账号必须有风格文件。无风格 → 提醒用户创建,不跳过。 - -### 单图模式提示词 - -每条文案生成: -- `imagePrompt`:画面描述(英文,给 Gemini/MJ) -- `videoPrompt`:运动描述(英文,给 Grok/VEO/Kling) - -videoPrompt 规则: -- 描述**运动**而非内容("zoom in" 而非 "a cat") -- 与 imagePrompt 画面内容对应 -- 简洁(1-2 句,不超过 50 词) -- **收敛原则**:基于图片已有内容,仅描述镜头运动和微动效果 -- **禁止**:大幅度环境切换、场景变化、人物位置跳变 -- **推荐写法**:镜头运动(slow zoom/pan/dolly)+ 星座/光效微动 + 保持静止氛围 -- **画幅继承**:manifest.json 顶层 `format` 字段(如 `"9:16"`)会自动传给 VEO/Kling,无需命令行 `-a` - -### 首尾帧模式提示词 - -每条文案生成: -- `imagePrompt`:起始帧画面(英文,与 single 模式复用同一字段) -- `lastFramePrompt`:结束帧画面(英文) -- `videoPrompt`:过渡描述(英文,给 VEO/Kling) - -**首尾帧提示词设计原则**: - -| 原则 | 说明 | 示例 | -|------|------|------| -| 同一场景 | 首尾帧是同一地点/主体的不同状态 | 都是工厂,不是两个地方 | -| 视角一致 | 相机角度/高度/距离相同 | 都是 wide shot | -| 状态对比 | imagePrompt"静止/之前",lastFramePrompt"运动/之后" | 空车间 → 生产线运转 | -| 过渡自然 | videoPrompt 描述从首到尾的变化 | "machines start up rhythmically" | -| 光照连贯 | 光源方向一致,可以有渐变 | 冷光 → 暖光可以,不能反转光源 | - -**videoPrompt 规则**(首尾帧): -- 描述**过渡过程**而非单帧状态 -- "from X to Y" 或 "X begins, Y happens" 格式 -- 必须同时呼应 imagePrompt(起始帧)和 lastFramePrompt(结束帧)中的元素 -- 简洁(1-2 句,不超过 50 词) +完整规则见 [prompt-rules.md](references/prompt-rules.md)。由子 Agent 读取并执行,主 Agent 审核提示词质量,不合格则退回重做。 --- diff --git a/.claude/skills/video-from-script/references/prompt-rules.md b/.claude/skills/video-from-script/references/prompt-rules.md new file mode 100644 index 0000000..2392710 --- /dev/null +++ b/.claude/skills/video-from-script/references/prompt-rules.md @@ -0,0 +1,46 @@ +# 提示词生成规则 + +**前置条件**:账号必须有风格文件。无风格 → 提醒用户创建,不跳过。 + +**输入**:分镜表 + style.md + account.json +**输出**:每个 shot 生成 imagePrompt / videoPrompt / keyword / keywordColor(英文) + +## 单图模式提示词 + +每条文案生成: +- `imagePrompt`:画面描述(英文,给 Gemini/MJ) +- `videoPrompt`:运动描述(英文,给 Grok/VEO/Kling) + +### videoPrompt 规则 + +- 描述**运动**而非内容("zoom in" 而非 "a cat") +- 与 imagePrompt 画面内容对应 +- 简洁(1-2 句,不超过 50 词) +- **收敛原则**:基于图片已有内容,仅描述镜头运动和微动效果 +- **禁止**:大幅度环境切换、场景变化、人物位置跳变 +- **推荐写法**:镜头运动(slow zoom/pan/dolly)+ 光效微动 + 保持静止氛围 +- **画幅继承**:manifest.json 顶层 `format` 字段(如 `"9:16"`)会自动传给 VEO/Kling,无需在 prompt 中指定 + +## 首尾帧模式提示词 + +每条文案生成: +- `imagePrompt`:起始帧画面(英文,与 single 模式复用同一字段) +- `lastFramePrompt`:结束帧画面(英文) +- `videoPrompt`:过渡描述(英文,给 VEO/Kling) + +### 首尾帧提示词设计原则 + +| 原则 | 说明 | 示例 | +|------|------|------| +| 同一场景 | 首尾帧是同一地点/主体的不同状态 | 都是工厂,不是两个地方 | +| 视角一致 | 相机角度/高度/距离相同 | 都是 wide shot | +| 状态对比 | imagePrompt"静止/之前",lastFramePrompt"运动/之后" | 空车间 → 生产线运转 | +| 过渡自然 | videoPrompt 描述从首到尾的变化 | "machines start up rhythmically" | +| 光照连贯 | 光源方向一致,可以有渐变 | 冷光 → 暖光可以,不能反转光源 | + +### videoPrompt 规则(首尾帧) + +- 描述**过渡过程**而非单帧状态 +- "from X to Y" 或 "X begins, Y happens" 格式 +- 必须同时呼应 imagePrompt(起始帧)和 lastFramePrompt(结束帧)中的元素 +- 简洁(1-2 句,不超过 50 词) diff --git a/.claude/skills/video-from-script/references/storyboard-rules.md b/.claude/skills/video-from-script/references/storyboard-rules.md new file mode 100644 index 0000000..2843221 --- /dev/null +++ b/.claude/skills/video-from-script/references/storyboard-rules.md @@ -0,0 +1,59 @@ +# 分镜规划规则 + +**分镜是纯叙事思考,与视觉风格无关。** 拿到文案后、读风格文件之前,先完成分镜。 + +短视频的画面节奏和文案节奏是脱钩的:TTS 配音连续流淌,画面在配音下面切换。分镜规划的是**视觉节拍**,不是文字断句。 + +## 输入输出 + +- **输入**:用户文案 + 约束(时长、shot 数、特殊要求) +- **输出**:结构化分镜表(JSON 数组) + +## 时长规划 + +分镜前先算数: +- 短视频目标时长:20-60 秒 +- 每个 shot 时长:6-8 秒(由视频模型决定) +- shot 数量 = 目标时长 / 6~8(取整,一般 4-8 个 shot) +- 配音字数 ≈ shot 数 x 12-15 字(按正常语速) + +## 分镜表字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `text` | string | 该 shot 覆盖的配音文案(可能不到一句,也可能跨句) | +| `shotType` | enum | `wide` / `medium` / `close-up` / `extreme-close-up` | +| `cameraMove` | enum | `static` / `zoom-in` / `zoom-out` / `pan-left` / `pan-right` / `dolly-in` / `tracking` | +| `visualDesc` | string | 画面描述(中文),只写三件事:**主体是什么、什么状态/动作、视觉焦点在哪**。氛围和构图交给风格层 | +| `hook` | boolean | 仅 shot 1 为 true,标记是否为开场钩子 | + +## 景别节奏 + +``` +shot 1 (hook): close-up 或 extreme-close-up,强主体,抓眼球 +shot 2: wide 或 medium,展开场景,给上下文 +shot 3-N(交替): close-up(压)→ wide(松)→ close-up(压)→ ... +最后一个 shot: medium 或 wide,收束,不过度设计 +``` + +不要用 extreme-close-up 收尾(太紧),不要用 tracking 滥用(信息密度低)。 + +## 镜头运动选择 + +| cameraMove | 情绪 | 典型场景 | +|------------|------|---------| +| `static` | 稳定、庄严 | 建筑、静物、仪式感 | +| `zoom-in` | 聚焦、压迫 | 悬疑、揭秘、强调细节 | +| `zoom-out` | 揭示、震撼 | 从局部拉出全景,揭示真相 | +| `pan-left/right` | 环顾、流动 | 展示空间、物品陈列 | +| `dolly-in` | 沉浸、紧张 | 人物面部、关键物件 | +| `tracking` | 跟随、活力 | 运动场景、行走(少用,AI 生成的 tracking 质量不稳定) | + +短视频默认转场是硬切,不需要单独字段。特殊转场(fade/dissolve)仅在判断需要情绪转换时标注在 `visualDesc` 里。 + +## 首尾帧额外规则 + +首尾帧模式下分镜需要额外注意: +- 每个 shot 必须能拆为两个有状态对比的画面(起始帧 / 结束帧) +- `visualDesc` 需描述状态变化方向:从什么状态到什么状态 +- 首尾帧必须在**同一场景**,仅状态不同 diff --git a/.claude/skills/video-from-script/scripts/pipeline.js b/.claude/skills/video-from-script/scripts/pipeline.js index 911e7bb..03e66a1 100644 --- a/.claude/skills/video-from-script/scripts/pipeline.js +++ b/.claude/skills/video-from-script/scripts/pipeline.js @@ -760,7 +760,7 @@ function initManifest(options) { String(date.getMonth() + 1).padStart(2, '0'), String(date.getDate()).padStart(2, '0'), ].join('') - const prefix = `${accountId}_${dateStr}` + const prefix = `${accountConfig.name}_${dateStr}` const outputBase = path.join(SKILLS_DIR, '..', '..', '..', 'output') ensureDir(outputBase)