feat(video-pipeline): 优化子 Agent 模板交互并新增模板路径工具
- 重构 SKILL.md,要求子 Agent 直接读取模板文件而非由主 Agent 摘要传送 - 新增 get-template-path.js 脚本,支持按账号和类型获取模板文件绝对路径 - 移除 capcut_assemble.js 中的关键字氛围词功能及相关依赖
This commit is contained in:
@@ -70,7 +70,21 @@ B 模式又分两种:**单图模式**(1 图 → 1 段视频)/ **首尾帧
|
|||||||
|
|
||||||
### Step 1: 分镜脚本(子 Agent 执行)
|
### Step 1: 分镜脚本(子 Agent 执行)
|
||||||
|
|
||||||
主 Agent 将**用户文案 + 分镜模板路径**交给子 Agent → 子 Agent 按模板输出分镜表 JSON:
|
主 Agent 获取账号专属模板路径 → 将**模板文件绝对路径 + 用户文案**传给子 Agent → 子 Agent **自行 Read 模板文件全文** → 按模板规则输出分镜表 JSON:
|
||||||
|
|
||||||
|
**模板路径获取方式**:
|
||||||
|
```bash
|
||||||
|
node .claude/skills/video-from-script/scripts/get-template-path.js --account <账号ID> --type storyboard
|
||||||
|
```
|
||||||
|
输出示例:`accounts\军事账号\prompts\分镜.md`
|
||||||
|
|
||||||
|
**子 Agent prompt 必须包含**:
|
||||||
|
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示子 Agent "先 Read 此文件全文,严格按模板规则执行"
|
||||||
|
2. 用户完整口播文案
|
||||||
|
3. 成片模式(图文/视频)
|
||||||
|
4. 输出格式要求(JSON 数组)
|
||||||
|
|
||||||
|
**禁止**:主 Agent 不得摘要模板内容传给子 Agent,必须让子 Agent 直接读文件。
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[{"id":1,"shotDesc":"英文画面描述","script":"中文口播文案","duration":5,"directorRef":"tarantino","keyword":"权力"}]
|
[{"id":1,"shotDesc":"英文画面描述","script":"中文口播文案","duration":5,"directorRef":"tarantino","keyword":"权力"}]
|
||||||
@@ -94,10 +108,16 @@ node scripts/pipeline.js init --account <id> --mode <single|framePair> \
|
|||||||
|
|
||||||
### Step 2-A: 图片提示词(子 Agent 执行)
|
### Step 2-A: 图片提示词(子 Agent 执行)
|
||||||
|
|
||||||
- 主 Agent 传**manifest 路径 + 图片提示词模板路径**给子 Agent
|
- 主 Agent 获取账号专属图片模板路径:`node .../get-template-path.js --account <账号ID> --type image`
|
||||||
- 子 Agent 读 manifest.items,为每个 shot 追加 `imagePrompt` 字段后回写 manifest
|
- 将**模板文件绝对路径 + manifest 绝对路径**传给子 Agent
|
||||||
|
- 子 Agent **先 Read 模板文件全文**,再 Read manifest.json 的 items,为每个 shot 追加 `imagePrompt` 字段后回写 manifest
|
||||||
- **硬约束:输出 shot 数量 == 输入 shot 数量**
|
- **硬约束:输出 shot 数量 == 输入 shot 数量**
|
||||||
|
|
||||||
|
**子 Agent prompt 必须包含**:
|
||||||
|
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示 "先 Read 此文件全文,严格按模板规则执行"
|
||||||
|
2. `manifest 绝对路径`,指示 "Read manifest.json 的 items 数组,为每个 item 生成 imagePrompt 后回写"
|
||||||
|
3. **禁止**:主 Agent 不得摘要模板内容传给子 Agent
|
||||||
|
|
||||||
**主 Agent 审查**:① 数量对得上?② shotDesc 内容完整保留?③ 光影策略对应 directorRef?
|
**主 Agent 审查**:① 数量对得上?② shotDesc 内容完整保留?③ 光影策略对应 directorRef?
|
||||||
|
|
||||||
### Step 2-B: 生图
|
### Step 2-B: 生图
|
||||||
@@ -113,10 +133,16 @@ node scripts/pipeline.js run --manifest <path> --phase images
|
|||||||
|
|
||||||
### Step 3-A: 视频提示词(B 模式专属,子 Agent 执行)
|
### Step 3-A: 视频提示词(B 模式专属,子 Agent 执行)
|
||||||
|
|
||||||
- 主 Agent 传**manifest 路径 + 视频提示词模板路径**给子 Agent
|
- 主 Agent 获取账号专属视频模板路径:`node .../get-template-path.js --account <账号ID> --type video`
|
||||||
- 子 Agent 读 manifest.items(含已确认分镜图路径),为每个 shot 生成 `videoPrompt` 后回写 manifest
|
- 将**模板文件绝对路径 + manifest 绝对路径**传给子 Agent
|
||||||
|
- 子 Agent **先 Read 模板文件全文**,再 Read manifest.items(含已确认分镜图路径),为每个 shot 生成 `videoPrompt` 后回写 manifest
|
||||||
- **硬约束:输出数量 == 分镜表 shot 数量**
|
- **硬约束:输出数量 == 分镜表 shot 数量**
|
||||||
|
|
||||||
|
**子 Agent prompt 必须包含**:
|
||||||
|
1. `模板文件绝对路径:{get-template-path.js 输出的路径,转为绝对路径}`,并指示 "先 Read 此文件全文,严格按模板规则执行"
|
||||||
|
2. `manifest 绝对路径`,指示 "Read manifest.json 的 items 数组,为每个 item 生成 videoPrompt 后回写"
|
||||||
|
3. **禁止**:主 Agent 不得摘要模板内容传给子 Agent
|
||||||
|
|
||||||
**主 Agent 审查**:① 数量对得上?② 描述运动而非内容?③ 字数 ≤ 50?
|
**主 Agent 审查**:① 数量对得上?② 描述运动而非内容?③ 字数 ≤ 50?
|
||||||
|
|
||||||
### Step 3-B: 生视频(B 模式专属)
|
### Step 3-B: 生视频(B 模式专属)
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ const fs = require('fs')
|
|||||||
const { US, parseArgs, getResolution, getAudioDurationSec } = require('./lib/capcut-api')
|
const { US, parseArgs, getResolution, getAudioDurationSec } = require('./lib/capcut-api')
|
||||||
const { buildTimeline, adjustVideoSpeed } = require('./lib/capcut-timeline')
|
const { buildTimeline, adjustVideoSpeed } = require('./lib/capcut-timeline')
|
||||||
const {
|
const {
|
||||||
loadAccountConfig, loadSubtitleStyle, loadKeywordStyle,
|
loadAccountConfig, loadSubtitleStyle,
|
||||||
loadKenBurns, loadTransitions,
|
loadKenBurns, loadTransitions,
|
||||||
addImages, addVideos, addKenBurns,
|
addImages, addVideos, addKenBurns,
|
||||||
addVoiceover, addBGM,
|
addVoiceover, addBGM,
|
||||||
addSubtitles, addKeywordOverlays,
|
addSubtitles,
|
||||||
addEffects, addFilter,
|
addEffects, addFilter,
|
||||||
} = require('./lib/capcut-tracks')
|
} = require('./lib/capcut-tracks')
|
||||||
const { saveManifest } = require('./lib/pipeline-utils')
|
const { saveManifest } = require('./lib/pipeline-utils')
|
||||||
@@ -239,7 +239,7 @@ async function assemble(args) {
|
|||||||
|
|
||||||
const steps = []
|
const steps = []
|
||||||
if (mode === 'images') steps.push('upload')
|
if (mode === 'images') steps.push('upload')
|
||||||
steps.push('draft', 'materials', 'kenburns', 'audio_oss', 'voiceover', 'audio', 'subtitles', 'keywords', 'effects', 'filter', 'save', 'sync')
|
steps.push('draft', 'materials', 'kenburns', 'audio_oss', 'voiceover', 'audio', 'subtitles', 'effects', 'filter', 'save', 'sync')
|
||||||
const totalSteps = steps.length
|
const totalSteps = steps.length
|
||||||
let step = 0
|
let step = 0
|
||||||
|
|
||||||
@@ -387,16 +387,7 @@ async function assemble(args) {
|
|||||||
console.log(' 跳过')
|
console.log(' 跳过')
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- 关键字氛围词 --
|
// -- 特效 -- // -- 特效 --
|
||||||
step++; console.log(`[${step}/${totalSteps}] 添加关键字氛围词...`)
|
|
||||||
const keywordStyle = loadKeywordStyle(manifest)
|
|
||||||
if (Object.keys(keywordStyle).length > 0 && items.some(i => i.keyword)) {
|
|
||||||
await addKeywordOverlays(draftUrl, items, timeline, keywordStyle)
|
|
||||||
} else {
|
|
||||||
console.log(' 跳过(无关键字或未配置 keywordStyle)')
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- 特效 --
|
|
||||||
step++; console.log(`[${step}/${totalSteps}] 添加特效...`)
|
step++; console.log(`[${step}/${totalSteps}] 添加特效...`)
|
||||||
if (finalEffects) {
|
if (finalEffects) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
103
.claude/skills/video-from-script/scripts/get-template-path.js
Normal file
103
.claude/skills/video-from-script/scripts/get-template-path.js
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取账号专属模板文件的完整路径
|
||||||
|
*
|
||||||
|
* 用法:
|
||||||
|
* node get-template-path.js --account 军事账号 --type storyboard
|
||||||
|
* node get-template-path.js --account 军事账号 --type image
|
||||||
|
* node get-template-path.js --account 军事账号 --type video
|
||||||
|
*
|
||||||
|
* 输出:
|
||||||
|
* 完整的绝对路径,可直接传给 Read 工具或 fs.readFileSync
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
// 路径常量
|
||||||
|
const SCRIPTS_DIR = path.join(__dirname, '..')
|
||||||
|
const SKILLS_DIR = path.join(SCRIPTS_DIR, '..')
|
||||||
|
const PROJECT_ROOT = path.join(SKILLS_DIR, '..', '..')
|
||||||
|
const ACCOUNTS_DIR = path.join(PROJECT_ROOT, 'accounts')
|
||||||
|
|
||||||
|
function getTemplatePath(accountId, templateType) {
|
||||||
|
// 1. 读取账号配置
|
||||||
|
const accountPath = path.join(ACCOUNTS_DIR, accountId, 'account.json')
|
||||||
|
if (!fs.existsSync(accountPath)) {
|
||||||
|
throw new Error(`账号不存在: ${accountPath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const account = JSON.parse(fs.readFileSync(accountPath, 'utf-8'))
|
||||||
|
|
||||||
|
// 2. 映射模板类型到字段名
|
||||||
|
const fieldMap = {
|
||||||
|
storyboard: 'storyboardPrompt',
|
||||||
|
image: 'imageStylePrompt',
|
||||||
|
video: 'videoStylePrompt'
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldName = fieldMap[templateType]
|
||||||
|
if (!fieldName) {
|
||||||
|
throw new Error(`未知模板类型: ${templateType},支持: storyboard, image, video`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 获取相对路径
|
||||||
|
const relativePath = account[fieldName]
|
||||||
|
if (!relativePath) {
|
||||||
|
throw new Error(`账号配置缺少字段: ${fieldName}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 判断是否为绝对路径
|
||||||
|
let absolutePath
|
||||||
|
if (path.isAbsolute(relativePath)) {
|
||||||
|
// 已经是绝对路径,直接使用
|
||||||
|
absolutePath = relativePath
|
||||||
|
} else {
|
||||||
|
// 相对路径,拼接账号目录(相对于账号目录)
|
||||||
|
absolutePath = path.join(ACCOUNTS_DIR, accountId, relativePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 检查文件是否存在
|
||||||
|
if (!fs.existsSync(absolutePath)) {
|
||||||
|
throw new Error(`模板文件不存在: ${absolutePath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 转换为相对于项目根目录的相对路径(子 Agent 友好)
|
||||||
|
const relativeToProject = path.relative(PROJECT_ROOT, absolutePath)
|
||||||
|
|
||||||
|
return relativeToProject
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CLI 入口
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const args = process.argv.slice(2)
|
||||||
|
|
||||||
|
const accountIndex = args.indexOf('--account')
|
||||||
|
const typeIndex = args.indexOf('--type')
|
||||||
|
|
||||||
|
if (accountIndex === -1 || typeIndex === -1) {
|
||||||
|
console.error('用法:node get-template-path.js --account <账号ID> --type <storyboard|image|video>')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountId = args[accountIndex + 1]
|
||||||
|
const templateType = args[typeIndex + 1]
|
||||||
|
|
||||||
|
try {
|
||||||
|
const fullPath = getTemplatePath(accountId, templateType)
|
||||||
|
console.log(fullPath)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`错误: ${err.message}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
main()
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getTemplatePath }
|
||||||
@@ -327,6 +327,44 @@ undone
|
|||||||
- 禁止写画质参数(`8K` / `cinematic`)——留给图片提示词
|
- 禁止写画质参数(`8K` / `cinematic`)——留给图片提示词
|
||||||
- **视频成片:** 禁止纯静止描述,必须附加至少一个隐性动势词
|
- **视频成片:** 禁止纯静止描述,必须附加至少一个隐性动势词
|
||||||
- **图文成片:** 禁止连续两张同景别/同构图的 shot
|
- **图文成片:** 禁止连续两张同景别/同构图的 shot
|
||||||
|
- **禁止剧透**:不能提前使用文案后续才出现的具体意象、物件、动作
|
||||||
|
|
||||||
|
### 6.7 语义-画面对齐规则(剧透、铺垫与承接)
|
||||||
|
|
||||||
|
**三定律**:
|
||||||
|
- **禁止剧透**:不能提前使用文案后续才出现的具体意象、物件、动作
|
||||||
|
- **允许铺垫**:当前画面可以暗示后续情绪趋势,但不使用具体意象
|
||||||
|
- **允许承接**:当前画面可以延续前一个镜头的情绪或视觉元素
|
||||||
|
|
||||||
|
**错误——剧透**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Shot 2 script: "这件事情你做的越多,运气就越差。"
|
||||||
|
Shot 3 script: "你把刀的把柄,亲手递给对方。"
|
||||||
|
|
||||||
|
Shot 2 shotDesc: "Close-up of hand gripping knife handle..." ❌ 剧透
|
||||||
|
→ "刀柄"是 Shot 3 才出现的意象,Shot 2 不能提前使用
|
||||||
|
```
|
||||||
|
|
||||||
|
**正确——铺垫**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Shot 2 shotDesc: "a figure standing at the edge of crumbling ground,
|
||||||
|
one hand slowly extends outward into darkness, not yet holding
|
||||||
|
anything, but the gesture has already begun" ✅ 铺垫
|
||||||
|
→ 暗示后续会有"递出"的动作,但没有剧透"刀柄"的具体意象
|
||||||
|
```
|
||||||
|
|
||||||
|
**正确——承接**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Shot 3 shotDesc: "the extended hand from the previous frame now
|
||||||
|
receives an unseen object — darkness conceals what passes
|
||||||
|
between the two figures" ✅ 承接
|
||||||
|
→ 延续 Shot 2 "伸出的手",动作连贯
|
||||||
|
```
|
||||||
|
|
||||||
|
**检查方法**:每条 shotDesc 写完后,只看当前 script + shotDesc——画面内容是否只来自当前这段文案?如果不是,重写。
|
||||||
|
|
||||||
## 七、directorRef 选择规则
|
## 七、directorRef 选择规则
|
||||||
|
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
|
|
||||||
| 参数 | 角色 | 规则 |
|
| 参数 | 角色 | 规则 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| **shotDesc** | 主输入 / 内容硬边界 | 画面里所有元素的来源,必须完整体现。不得替换、删减或用其他内容覆盖。imagePrompt 的内容层 100% 来自 shotDesc |
|
| **shotDesc** | 主内容 / 画面硬边界 | 画面里所有视觉元素的来源之一,必须完整体现。不得替换、删减 |
|
||||||
| **当前旁白** | 聚焦核心 / 情绪与氛围 | 理解当前 Shot 的情绪基调和语义重点。用于提取:情绪强度、关键意象、构图暗示。不得用旁白内容替代或扩展 shotDesc 的画面描述 |
|
| **当前旁白(script)** | 主内容 / 情绪与意象 | 与 shotDesc 共同构成画面主线。从中提取情绪基调、关键意象、构图暗示。与 shotDesc 一起决定画面内容 |
|
||||||
| **完整文案** | 叙事上下文 / 氛围参考 | 仅用于理解当前 Shot 在整体视频中的叙事位置。决定情绪强度(开场/高潮/收尾)。不得将其他段落的内容引入当前画面 |
|
| **完整文案** | 仅氛围参考 / 不影响画面内容 | 仅用于理解整体氛围、情绪浓度和核心主题。**禁止将其他段落的意象、物件、动作引入当前画面** |
|
||||||
| **directorRef** | 光影风格来源 | 由上游分镜脚本生成器指定,本层只执行光影渲染层。不改变 shotDesc 的构图内容,只改变光如何落在画面上。可选值:`tarantino` / `kitano` / `fincher` |
|
| **directorRef** | 光影风格来源 | 由上游分镜指定,本层只执行光影渲染层。不改变 shotDesc 的构图内容,只改变光如何落在画面上。可选值:`tarantino` / `kitano` / `fincher` |
|
||||||
| **账号风格** | 视觉身份注入 | 由账号配置文件提供画风、色彩、质感参数。直接替换第五节「固定风格词尾」的占位内容 |
|
| **账号风格** | 视觉身份注入 | 由账号配置文件提供画风、色彩、质感参数。直接替换第五节「固定风格词尾」的占位内容 |
|
||||||
|
|
||||||
**一句话总结:** shotDesc 决定画什么,旁白决定情绪浓度,完整文案决定叙事分量,directorRef 决定光怎么落,账号风格决定整体画风。
|
**一句话总结:** shotDesc + 当前旁白共同决定画什么,完整文案只提供氛围参考,directorRef 决定光怎么落,账号风格决定整体画风。
|
||||||
|
|
||||||
## 三、导演光影词库(图片层专用)
|
## 三、导演光影词库(图片层专用)
|
||||||
|
|
||||||
@@ -162,10 +162,46 @@ Vertical format, aspect ratio [账号画幅].
|
|||||||
[完整提示词,可直接复制使用]
|
[完整提示词,可直接复制使用]
|
||||||
```
|
```
|
||||||
|
|
||||||
## 九、质量自检清单
|
## 九、语义-画面对齐规则(强制)
|
||||||
|
|
||||||
|
### 三定律
|
||||||
|
|
||||||
|
- **禁止剧透**:不能在 imagePrompt 中引入文案后续才出现的具体意象、物件、动作
|
||||||
|
- **允许铺垫**:画面可以暗示后续情绪趋势(如光影变暗、空间收窄),但不使用具体意象
|
||||||
|
- **允许承接**:可以延续前一个镜头的情绪氛围或视觉元素
|
||||||
|
|
||||||
|
### 错误示例——剧透
|
||||||
|
|
||||||
|
```
|
||||||
|
shotDesc: "a figure standing at the edge of a crumbling platform"
|
||||||
|
当前旁白: "这件事情你做的越多,运气就越差。"
|
||||||
|
完整文案后续: "你把刀的把柄,亲手递给对方。"
|
||||||
|
|
||||||
|
❌ 剧透: "...a hand gripping a knife handle..."
|
||||||
|
→ shotDesc 里没有刀,是文案后面才出现的意象
|
||||||
|
```
|
||||||
|
|
||||||
|
### 正确示例——铺垫
|
||||||
|
|
||||||
|
```
|
||||||
|
✅ 铺垫: "...a figure at the edge of crumbling ground, one hand
|
||||||
|
slowly extends into darkness, not yet holding anything — [光影词]..."
|
||||||
|
→ 手伸出但没握住东西,暗示后续"递出"但没剧透"刀柄"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 检查方法
|
||||||
|
|
||||||
|
> 画面中每个视觉元素,都能在 shotDesc + 当前旁白中找到对应吗?
|
||||||
|
> 有任何元素只出现在文案后续段落但当前旁白没提?
|
||||||
|
> 铺垫用的是情绪暗示还是具体物件?(必须前者)
|
||||||
|
> 有问题 → **删除该元素,重写**
|
||||||
|
|
||||||
|
## 十、质量自检清单
|
||||||
|
|
||||||
- [ ] shotDesc 的主体和动势完整体现(不得缺失或替换)
|
- [ ] shotDesc 的主体和动势完整体现(不得缺失或替换)
|
||||||
- [ ] 未引入其他 Shot 的内容
|
- [ ] 未引入其他 Shot 的具体意象(禁止剧透)
|
||||||
|
- [ ] 允许铺垫:情绪暗示可以,具体物件不行
|
||||||
|
- [ ] 允许承接:延续前一镜头情绪可以
|
||||||
- [ ] 画面是「趋势中的瞬间」非「已完成状态」
|
- [ ] 画面是「趋势中的瞬间」非「已完成状态」
|
||||||
- [ ] 光影词库对应 directorRef,未混用其他导演
|
- [ ] 光影词库对应 directorRef,未混用其他导演
|
||||||
- [ ] 账号风格词尾已替换,非占位文本
|
- [ ] 账号风格词尾已替换,非占位文本
|
||||||
|
|||||||
@@ -12,17 +12,17 @@
|
|||||||
|
|
||||||
| 参数 | 角色 | 规则 |
|
| 参数 | 角色 | 规则 |
|
||||||
|------|------|------|
|
|------|------|------|
|
||||||
| **shotDesc** | 主输入 / 画面硬边界 | 定义画面里有什么、人物姿态、环境。运动设计从 shotDesc 的隐性动势出发并放大。不得替换场景或重新设计人物 |
|
| **shotDesc** | 主内容 / 画面硬边界 | 定义画面里有什么、人物姿态、环境。运动设计从 shotDesc 的隐性动势出发并放大。不得替换场景或重新设计人物 |
|
||||||
| **当前旁白** | 聚焦核心 / 运动的灵魂 | 提取情绪节奏 → 对应运动的快慢。提取关键动词和意象 → 转化为具体画面动势。提取暗喻/比喻 → 转化为视觉运动设计。不得用旁白内容替代 shotDesc 的画面主体 |
|
| **当前旁白(script)** | 主内容 / 运动的灵魂 | 与 shotDesc 共同构成运动主线。提取情绪节奏 → 对应运动的快慢。提取关键动词和意象 → 转化为具体画面动势。提取暗喻/比喻 → 转化为视觉运动设计 |
|
||||||
| **完整文案** | 叙事上下文 / 运动强度参考 | 理解当前 Shot 的叙事位置(开场/高潮/收尾)。决定运动幅度和情绪强度。不得将其他段落内容引入当前片段 |
|
| **完整文案** | 仅氛围参考 / 不影响画面内容 | 仅用于理解整体氛围、情绪浓度和核心主题。**禁止将其他段落的意象、物件、动作引入当前片段** |
|
||||||
| **directorRef** | 运动风格来源 | 由上游分镜脚本生成器指定,本层只执行运动节奏层。不改变 shotDesc 的画面内容,只改变运动如何发生。可选值:`tarantino` / `kitano` / `fincher` |
|
| **directorRef** | 运动风格来源 | 由上游分镜指定,本层只执行运动节奏层。不改变 shotDesc 的画面内容,只改变运动如何发生。可选值:`tarantino` / `kitano` / `fincher` |
|
||||||
| **账号运动风格** | 运动基调约束 | 由账号配置文件提供运动风格基调(克制/激烈/缓慢等)。约束整体运动幅度,导演词库在此范围内执行 |
|
| **账号运动风格** | 运动基调约束 | 由账号配置文件提供运动风格基调(克制/激烈/缓慢等)。约束整体运动幅度,导演词库在此范围内执行 |
|
||||||
|
|
||||||
**运动来源优先级:**
|
**运动来源优先级:**
|
||||||
|
|
||||||
旁白意象 > shotDesc 隐性动势 > directorRef 运动模板
|
当前旁白意象 > shotDesc 隐性动势 > directorRef 运动模板
|
||||||
|
|
||||||
> 从文案里找运动的理由,导演风格是执行方式,不是内容来源。
|
> 从当前旁白里找运动的理由,导演风格是执行方式,不是内容来源。
|
||||||
|
|
||||||
## 三、导演运动词库(视频层专用)
|
## 三、导演运动词库(视频层专用)
|
||||||
|
|
||||||
@@ -250,10 +250,12 @@ Vertical format 9:16, [X] seconds, cinematic, no text.
|
|||||||
- [ ] 覆盖三层运动中的至少两层
|
- [ ] 覆盖三层运动中的至少两层
|
||||||
- [ ] 主体运动有具体身体部位,非抽象情绪词
|
- [ ] 主体运动有具体身体部位,非抽象情绪词
|
||||||
- [ ] 镜头运动来自 directorRef 对应词库,未混用其他导演
|
- [ ] 镜头运动来自 directorRef 对应词库,未混用其他导演
|
||||||
- [ ] 从旁白中提取了意象并转化为运动设计
|
- [ ] 从当前旁白中提取了意象并转化为运动设计
|
||||||
- [ ] 未引入其他 Shot 的内容
|
- [ ] 未引入其他 Shot 的具体意象(禁止剧透)
|
||||||
|
- [ ] 允许铺垫:运动可以暗示后续情绪趋势,但不使用具体物件
|
||||||
|
- [ ] 允许承接:运动可以延续前一片段的动势方向
|
||||||
- [ ] 片段结尾留有余势
|
- [ ] 片段结尾留有余势
|
||||||
- [ ] 语言和参数格式与目标模型匹配
|
- [ ] 语言和参数格式与目标模型匹配
|
||||||
- [ ] 视频第一帧 = 静态分镜图状态,对不上则整个片段脱锚
|
- [ ] 视频第一帧 = 静态分镜图状态,对不上则整个片段脱锚
|
||||||
- [ ] directorRef 只影响运动节奏层,画面内容始终来自 shotDesc
|
- [ ] directorRef 只影响运动节奏层,画面内容始终来自 shotDesc
|
||||||
- [ ] 运动来源优先级:旁白意象 > shotDesc隐性动势 > 导演运动模板
|
- [ ] 运动来源优先级:当前旁白意象 > shotDesc隐性动势 > 导演运动模板
|
||||||
|
|||||||
@@ -351,6 +351,54 @@ something that cannot be undone
|
|||||||
- **视频成片:** 禁止纯静止描述,必须附加至少一个隐性动势词
|
- **视频成片:** 禁止纯静止描述,必须附加至少一个隐性动势词
|
||||||
- **图文成片:** 禁止连续两张同景别/同构图的 shot
|
- **图文成片:** 禁止连续两张同景别/同构图的 shot
|
||||||
- 禁止出现真实政治人物姓名
|
- 禁止出现真实政治人物姓名
|
||||||
|
- **禁止意象提前透支**:shotDesc 的画面内容必须严格匹配当前 script 的语义,不能提前消费文案后续才出现的隐喻、意象或物件
|
||||||
|
|
||||||
|
### 7.7 语义-画面对齐规则
|
||||||
|
|
||||||
|
**核心原则**:每个 Shot 的 shotDesc 画面必须从当前 script 提取视觉元素,禁止从文案的其他段落借用意象。
|
||||||
|
|
||||||
|
**三定律**:
|
||||||
|
- **禁止剧透**:不能提前使用文案后续才出现的具体意象、物件、动作
|
||||||
|
- **允许铺垫**:当前画面可以暗示后续情绪趋势,但不使用具体意象
|
||||||
|
- **允许承接**:当前画面可以延续前一个镜头的情绪或视觉元素
|
||||||
|
|
||||||
|
**错误——剧透(意象提前透支)**:
|
||||||
|
|
||||||
|
文案原文:
|
||||||
|
```
|
||||||
|
Shot 2 script: "这件事情你做的越多,你的人生风水和你的运气就越差。"
|
||||||
|
Shot 3 script: "为什么?解释这个动作,底层是在做一件事——你把刀的把柄,亲手递给对方。"
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Shot 2 shotDesc: "Close-up of hand gripping knife handle..." ❌ 剧透
|
||||||
|
```
|
||||||
|
|
||||||
|
→ "刀柄"意象在 Shot 3 的文案才出现,Shot 2 不能提前使用。
|
||||||
|
|
||||||
|
**正确——铺垫**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Shot 2 shotDesc: "a figure standing at the edge of a crumbling platform,
|
||||||
|
shadows lengthening beneath, the ground beneath the boots beginning
|
||||||
|
to crack and give way — one hand slowly extends outward into
|
||||||
|
darkness, not yet holding anything, but the gesture has already
|
||||||
|
begun" ✅ 铺垫
|
||||||
|
```
|
||||||
|
|
||||||
|
→ 画面从"运气越差"提取"崩塌/衰败"意象。"手伸出但还没握住东西"是铺垫——暗示后续会有"递出"的动作,但没有剧透"刀柄"的具体意象。
|
||||||
|
|
||||||
|
**正确——承接**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Shot 3 shotDesc: "the extended hand from the previous frame now receives
|
||||||
|
an unseen object — darkness conceals what passes between the two figures"
|
||||||
|
✅ 承接
|
||||||
|
```
|
||||||
|
|
||||||
|
→ 延续 Shot 2 "伸出的手",现在"接住了东西"。画面承接前一个镜头的动作,同时"暗处遮住了物件"保留了悬念。
|
||||||
|
|
||||||
|
**检查方法**:每条 shotDesc 写完后,遮住其他所有 Shot,只看当前 script + shotDesc——画面内容是否只来自当前这段文案?如果不是,重写。
|
||||||
|
|
||||||
## 八、directorRef 选择规则
|
## 八、directorRef 选择规则
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@
|
|||||||
|
|
||||||
| 参数 | 角色 | 使用规则 |
|
| 参数 | 角色 | 使用规则 |
|
||||||
|-----|------|---------|
|
|-----|------|---------|
|
||||||
| **shotDesc** | 主输入 / 内容硬边界 | 画面里所有元素的来源,必须完整体现;不得替换、删减或用其他内容覆盖;imagePrompt 的内容层 100% 来自 shotDesc |
|
| **shotDesc** | 主内容 / 画面硬边界 | 画面里所有视觉元素的来源之一,必须完整体现;不得替换、删减 |
|
||||||
| **当前旁白** | 聚焦核心 / 情绪与氛围 | 理解当前 Shot 的情绪基调和语义重点;用于提取:情绪强度、关键意象、构图暗示;不得用旁白内容替代或扩展 shotDesc 的画面描述 |
|
| **当前旁白(script)** | 主内容 / 情绪与意象 | 与 shotDesc 共同构成画面主线;从中提取情绪基调、关键意象、构图暗示;与 shotDesc 一起决定画面内容 |
|
||||||
| **完整文案** | 叙事上下文 / 氛围参考 | 仅用于理解当前 Shot 在整体视频中的叙事位置;决定情绪强度(开场 / 高潮 / 收尾);不得将其他段落的内容引入当前画面 |
|
| **完整文案** | 仅氛围参考 / 不影响画面内容 | 仅用于理解整体氛围、情绪浓度和核心主题;**禁止将其他段落的意象、物件、动作引入当前画面** |
|
||||||
| **directorRef** | 光影风格来源 / 向下游透传 | 由上游分镜脚本生成器指定,本层只执行光影渲染层;不改变 shotDesc 的构图内容,只改变光如何落在画面上;可选值:tarantino / kitano / fincher |
|
| **directorRef** | 光影风格 / 向下游透传 | 由上游分镜指定,本层只执行光影渲染;不改变 shotDesc 的构图内容,只改变光如何落在画面上;可选值:tarantino / kitano / fincher |
|
||||||
|
|
||||||
一句话总结:shotDesc 决定画什么,旁白决定情绪浓度,完整文案决定叙事分量,directorRef 决定光怎么落。
|
一句话总结:**shotDesc + 当前旁白共同决定画什么**,完整文案只提供氛围参考,directorRef 决定光怎么落。
|
||||||
|
|
||||||
## 三、账号视觉基础风格(所有导演共用底层)
|
## 三、账号视觉基础风格(所有导演共用底层)
|
||||||
|
|
||||||
@@ -240,7 +240,60 @@ edge-to-edge, no border, no frame, no text, no watermark
|
|||||||
--ar 9:16 --style raw --q 2 --v 6.1
|
--ar 9:16 --style raw --q 2 --v 6.1
|
||||||
```
|
```
|
||||||
|
|
||||||
## 十、质量自检清单
|
## 十、语义-画面对齐规则
|
||||||
|
|
||||||
|
### 10.1 核心原则
|
||||||
|
|
||||||
|
imagePrompt 的画面内容 **100% 来自 shotDesc**。shotDesc 是上游分镜脚本对画面的精确设计,本层只负责渲染(光影、色调、质感),**禁止修改、替换或扩展画面内容**。
|
||||||
|
|
||||||
|
### 10.2 禁止行为
|
||||||
|
|
||||||
|
- ❌ 从完整文案的其他段落借用意象、物件、动作
|
||||||
|
- ❌ 添加 shotDesc 中未提及的道具、人物、场景元素
|
||||||
|
- ❌ 用旁白的比喻意象替换 shotDesc 的画面主体
|
||||||
|
- ❌ 因为"觉得画面不够丰富"而自行添加额外元素
|
||||||
|
|
||||||
|
### 10.3 剧透、铺垫与承接
|
||||||
|
|
||||||
|
**三定律**:
|
||||||
|
- **禁止剧透**:不能在 imagePrompt 中引入文案后续才出现的具体意象、物件、动作
|
||||||
|
- **允许铺垫**:画面可以暗示后续情绪趋势(如光影变暗、空间收窄),但不使用具体意象
|
||||||
|
- **允许承接**:可以延续前一个镜头的情绪氛围或视觉元素
|
||||||
|
|
||||||
|
**错误——剧透**:
|
||||||
|
|
||||||
|
```
|
||||||
|
shotDesc: "a figure standing at the edge of a crumbling platform,
|
||||||
|
shadows lengthening beneath"
|
||||||
|
当前旁白: "这件事情你做的越多,你的人生运气就越差。"
|
||||||
|
完整文案中后续提到: "你把刀的把柄,亲手递给对方。"
|
||||||
|
|
||||||
|
❌ 剧透 imagePrompt:
|
||||||
|
"...a hand gripping a knife handle, knuckles white..."
|
||||||
|
→ shotDesc 里没有刀,是文案后面才出现的意象
|
||||||
|
```
|
||||||
|
|
||||||
|
**正确——铺垫**:
|
||||||
|
|
||||||
|
```
|
||||||
|
✅ 铺垫 imagePrompt:
|
||||||
|
"...a figure standing at the edge of a crumbling platform,
|
||||||
|
shadows lengthening beneath, one hand slowly extends outward
|
||||||
|
into darkness, not yet holding anything — [光影词], [画风词]..."
|
||||||
|
→ 严格按 shotDesc 渲染,手伸出但没握住东西,
|
||||||
|
暗示后续会有"递出"但没剧透"刀柄"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.4 检查方法
|
||||||
|
|
||||||
|
生成 imagePrompt 后,逐项核对:
|
||||||
|
|
||||||
|
> 画面中每个视觉元素,都能在 shotDesc + 当前旁白中找到对应描述吗?
|
||||||
|
> 有任何元素只出现在文案后续段落但当前旁白没提?
|
||||||
|
> 铺垫用的是情绪暗示还是具体物件?(必须前者)
|
||||||
|
> 答案有问题的 → **删除该元素,重写**
|
||||||
|
|
||||||
|
## 十一、质量自检清单
|
||||||
|
|
||||||
- shotDesc 的主体和动势完整体现(不得缺失或替换)
|
- shotDesc 的主体和动势完整体现(不得缺失或替换)
|
||||||
- 是否引入了其他 Shot 的内容(禁止)
|
- 是否引入了其他 Shot 的内容(禁止)
|
||||||
|
|||||||
@@ -12,13 +12,13 @@
|
|||||||
|
|
||||||
| 参数 | 角色 | 使用规则 |
|
| 参数 | 角色 | 使用规则 |
|
||||||
|-----|------|---------|
|
|-----|------|---------|
|
||||||
| **shotDesc** | 主输入 / 画面硬边界 | 定义画面里有什么、人物姿态、环境;运动设计从 shotDesc 的隐性动势出发并放大;不得替换场景或重新设计人物 |
|
| **shotDesc** | 主内容 / 画面硬边界 | 定义画面里有什么、人物姿态、环境;运动设计从 shotDesc 的隐性动势出发并放大;不得替换场景或重新设计人物 |
|
||||||
| **当前旁白** | 聚焦核心 / 运动的灵魂 | 提取情绪节奏 → 对应运动的快慢;提取关键动词和意象 → 转化为具体画面动势;提取暗喻/比喻 → 转化为视觉运动设计;不得用旁白内容替代 shotDesc 的画面主体 |
|
| **当前旁白(script)** | 主内容 / 运动的灵魂 | 与 shotDesc 共同构成运动主线;提取情绪节奏 → 对应运动的快慢;提取关键动词和意象 → 转化为具体画面动势;提取暗喻/比喻 → 转化为视觉运动设计 |
|
||||||
| **完整文案** | 叙事上下文 / 运动强度参考 | 理解当前 Shot 的叙事位置(开场/高潮/收尾);决定运动幅度和情绪强度;不得将其他段落内容引入当前片段 |
|
| **完整文案** | 仅氛围参考 / 不影响画面内容 | 仅用于理解整体氛围、情绪浓度和核心主题;**禁止将其他段落的意象、物件、动作引入当前片段** |
|
||||||
| **directorRef** | 运动风格来源 / 向下游透传 | 由上游分镜脚本生成器指定,本层只执行运动节奏层;不改变 shotDesc 的画面内容,只改变运动如何发生;可选值:tarantino / kitano / fincher |
|
| **directorRef** | 运动风格 / 向下游透传 | 由上游分镜指定,本层只执行运动节奏层;不改变 shotDesc 的画面内容,只改变运动如何发生;可选值:tarantino / kitano / fincher |
|
||||||
|
|
||||||
运动来源优先级:旁白意象 > shotDesc 隐性动势 > directorRef 运动模板
|
运动来源优先级:当前旁白意象 > shotDesc 隐性动势 > directorRef 运动模板
|
||||||
从文案里找运动的理由,导演风格是执行方式,不是内容来源
|
从当前旁白里找运动的理由,导演风格是执行方式,不是内容来源
|
||||||
|
|
||||||
## 三、账号视觉运动基础风格(固定,不因导演而变)
|
## 三、账号视觉运动基础风格(固定,不因导演而变)
|
||||||
|
|
||||||
@@ -312,8 +312,10 @@ shotDesc「knuckles beginning to whiten」
|
|||||||
- 覆盖三层运动中的至少两层
|
- 覆盖三层运动中的至少两层
|
||||||
- 主体运动有具体身体部位,非抽象情绪词
|
- 主体运动有具体身体部位,非抽象情绪词
|
||||||
- 镜头运动来自 directorRef 对应词库,未混用其他导演
|
- 镜头运动来自 directorRef 对应词库,未混用其他导演
|
||||||
- 从旁白中提取了意象并转化为运动设计
|
- 从当前旁白中提取了意象并转化为运动设计
|
||||||
- 未引入其他 Shot 的内容
|
- 未引入其他 Shot 的具体意象(禁止剧透)
|
||||||
|
- 允许铺垫:运动可以暗示后续情绪趋势,但不使用具体物件
|
||||||
|
- 允许承接:运动可以延续前一片段的动势方向
|
||||||
- 运动幅度符合账号「隐忍张力」基调
|
- 运动幅度符合账号「隐忍张力」基调
|
||||||
- 片段结尾留有余势
|
- 片段结尾留有余势
|
||||||
- 语言和参数格式与目标模型匹配
|
- 语言和参数格式与目标模型匹配
|
||||||
|
|||||||
Reference in New Issue
Block a user