- SKILL.md: 新增工作流阶段定义、质量卡点、分镜规则 - manifest-schema.md: 补充完整字段规范及类型定义 - phase-tts.js: 优化 TTS 合成长逻辑,添加进度追踪 - capcut-tracks.js: 扩展轨道构建能力,支持更多元素类型 - capcut-timeline.js: 改进时间线生成,支持淡入淡出 - capcut_assemble.js: 新增 assemble 阶段完整实现 - cmd-init.js: 完善 init 命令逻辑 - qwen-tts.js: 调整超时配置 - accounts/禁忌帝王学: 更新拆分/图像/台词提示词 - accounts/健身跟练: 新增账号含 account.json 及全套提示词模板 - 新增 workflow-issues-20260501.md 参考文档 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
manifest.json 规范
pipeline.js init创建,Pipeline 执行,Agent 审查。禁止 AI 手写 manifest.json,必须通过
pipeline.js init初始化。脚本从 account.json 自动继承结构字段,AI 只提供创意内容(items 的 shotDesc/script/imagePrompt 等)。
创建方式
# Step 2-0:分镜确认后立即初始化(imagePrompt/videoPrompt 后续补充)
node scripts/pipeline.js init --account 军事账号 --mode single \
--items '[{"shotDesc":"英文画面描述","script":"中文口播文案","duration":5,"directorRef":"tarantino","keyword":"权力"}]'
# 或从文件读取
node scripts/pipeline.js init --account 军事账号 --mode single --items-file ./items.json
# Step 2-C 人工确认
node scripts/pipeline.js confirm --manifest <path> --all
node scripts/pipeline.js confirm --manifest <path> --items 1,3,5
# 校验已有 manifest
node scripts/pipeline.js validate --manifest <path>
顶层字段
| 字段 | 说明 | 来源 | 谁填充 |
|---|---|---|---|
account |
账号 ID | account.json | init 自动 |
imageModel |
gemini / mj |
account.json | init 自动 |
videoModel |
veo3-fast-frames / grok-video-3 / kling 等 |
account.json | init 自动 |
format |
画幅:9:16 / 16:9 |
account.json | init 自动 |
estimatedVideoDuration |
视频模型固定时长(秒),顶层冗余字段 | videoModel 查表 | init 自动,assemble 直接读 |
mode |
single 单图 / framePair 首尾帧 |
CLI 参数 | init 自动 |
references |
参考图数组,从 account.json styles.*.references 搬入 | account.json | init 自动 |
items |
素材数组(AI 提供创意内容) | CLI --items | AI → init |
references 字段
从 account.json 搬入,pipeline 直接使用,不再回读 account.json。
- Gemini → 读
file(本地路径,图生图用) - MJ → 读
url(公网 URL,--sref用)
items[] 字段
Agent 写入(创建时)
| 字段 | 说明 |
|---|---|
status |
固定写 "pending" |
shotDesc |
英文分镜描述(含隐性动势,40-80词) |
script |
该 shot 的语义子句原文(完整句拆分后的子段,一字不差) |
duration |
TTS 估算秒数(= script字数÷5),必须 ≤ 6s |
estimatedAudioDuration |
同 duration,备选别名 |
estimatedVideoDuration |
视频模型固定时长(Kling=6s, VEO=8s, Grok=6s),pipeline init 时自动填入 |
imagePrompt |
英文画面描述(给 Gemini/MJ),Step 2-A 生成 |
directorRef |
导演构图参考(tarantino / kitano / fincher),三层透传 |
keyword |
关键字氛围词(2-6 字),assemble 时以花字效果叠加在画面中央。可选 |
confirmed |
人工确认状态,默认 false |
强制约束:
- 每个 shot 的
duration(TTS估算)必须 ≤ 6s,否则 pipeline 拒绝执行 script必须是语义子句,完整句直接填入多个 shot 是严重错误estimatedVideoDuration在 manifest 初始化时由pipeline.js init从 videoModel 自动推算:kling→6veo3-fast/veo3-fast-frames→8grok-video-3→6
- assemble 阶段通过
ratio = estimatedVideoDuration / realAudioDuration选择适配策略
Agent 后续回写(Step 3-A 视频提示词)
| 字段 | 说明 | 写入时机 |
|---|---|---|
videoPrompt |
英文运动描述(给 Grok/VEO/Kling),描述镜头运动而非内容 | Step 3-A 由 Agent 回写 |
Pipeline 回写(执行后)
| 字段 | 说明 | 写入阶段 |
|---|---|---|
status |
pending → generating → done / failed |
images |
file |
生成的图片路径(相对 manifest) | images |
candidates |
MJ 拆分的 4 张候选图路径(Gemini 无此字段) | images |
url |
图片 OSS 公网 URL | upload |
confirmed |
人工确认后设为 true |
confirm |
video |
生成的视频路径 | videos |
videoDuration |
视频实测时长(秒),Kling=6, VEO=8, Grok=6 | videos |
videoUrl |
视频 OSS 公网 URL | videos |
audio |
TTS 音频路径 | tts |
audioDuration |
音频实测时长(秒) | tts |
segments |
分句音频数组(仅多句时存在),见下方 | tts |
Agent 审查时可操作
- MJ 换选:
item.file = item.candidates[2] - 删除不合格 item:直接从 items 数组移除,重新跑
--phase images - 调整 prompt 重跑:改
imagePrompt,status 改回pending - 人工确认:
node scripts/pipeline.js confirm --manifest <path> --all
状态机
item 生命周期
pending → [images] → done → [confirm] → confirmed=true → [upload: url填入] → [videos] → done → [tts] → done
↓ ↓
failed failed + error
status 一旦进入 done 就不再回退。后续阶段通过检查"有前置字段 + 无后置字段"来识别待处理 item,不依赖 status 变化。
各阶段拾取条件
Agent 不需要记住这些条件,pipeline 内部自动匹配。仅供理解原理:
| 阶段 | item 被拾取的条件 |
|---|---|
| images | status=pending + 有 imagePrompt |
| upload | status=done + 有 file + 无 url |
| videos | status=done + confirmed=true + 有 url + 有 videoPrompt + 无 video |
| tts | status=done + 有 script(回退 text) + 无 audio |
pipeline.phases 整体状态
每个阶段有独立状态:pending → running → done / partial / failed
done— 全部 item 成功partial— 部分 item 失败(其他成功)failed— 阶段整体异常中断
失败处理
用 --retry-failed 一条命令搞定。
根据失败阶段选择操作
图片生成失败(images 阶段 partial):
# 只改 prompt 不改图片风格 → 重试即可
node scripts/pipeline.js run --manifest <path> --phase images --retry-failed
# 需要换 prompt → 先改 item.imagePrompt,再重试
# (改完后跑上面同一条命令)
视频生成失败(videos 阶段 partial):
# API 临时故障、网络超时 → 直接重试
node scripts/pipeline.js run --manifest <path> --phase videos --retry-failed
# 提示词问题 → 先改 item.videoPrompt,再重试
# (改完后跑上面同一条命令)
# 视频模型不可用 → 改 manifest.videoModel 或 account.json,再重试
全阶段重试:
node scripts/pipeline.js run --manifest <path> --retry-failed
--retry-failed 内部行为
- 扫描所有
status=failed或status=partial的 item - 根据已有字段自动判断应重置到哪个阶段:
- 有
url+videoPrompt+ 无video→ 重置为可生视频(status=done) - 无
url+ 有imagePrompt→ 重置为可生图(status=pending)
- 有
- 对应
pipeline.phases重置为pending - 清除
error字段 - 正常执行指定阶段
首尾帧模式
mode: "framePair" 时,imagePrompt 作为起始帧,每个 item 额外字段:
| 字段 | 说明 | 谁填充 |
|---|---|---|
imagePrompt |
起始帧画面描述(与 single 模式复用同一字段) | AI |
lastFramePrompt |
结束帧画面描述 | AI |
lastFrame |
结束帧图片路径 | pipeline images 回写 |
lastFrameUrl |
结束帧 OSS URL | pipeline upload 回写 |
首尾帧规则:同一场景、视角一致、状态对比。VEO 检测到 lastFrameUrl 自动启用双图模式。
目录结构
output/{name}_{YYYYMMDD}_{NNN}/
├── manifest.json # 主清单
├── images/ # scene_{NN}_{slug}.jpeg(首尾帧加 _last,MJ 候选加 _cand{1-4})
├── videos/ # scene_{NN}_{slug}.mp4
└── audio/ # seg_001.mp3
slug 从 shotDesc 派生(slugify: 保留中文和字母数字,最多 20 字符)。
segments[] 字段(TTS 分句)
TTS 阶段统一生成,单句时数组仅 1 个元素,多句时 N 个元素。assemble 阶段直接使用各 segment 的实际音频时长对齐字幕。
| 字段 | 说明 |
|---|---|
text |
分句文本(已去除标点) |
audio |
该句音频路径(相对 manifest) |
duration |
该句音频时长(秒) |
item.audio 指向 segments[0].audio,item.audioDuration 为各段累计时长。assemble 阶段遍历 segments 逐一添加音频和字幕,使用实际文件时长(非比例分配),确保音频与字幕精确同步,消除留白。
成片时间线规则
核心原则:
- 文案是时间轴唯一锚点
- TTS 语速固定 1.15x(写死在 qwen-tts.js),音频导入 CapCut 时不可调速
- 音频时长是主时间线:每个 shot 的 TTS 估算必须 ≤ 视频模型固定时长
- 视频必须 ≥ 音频:audioDur > videoDur 的 shot 在分镜阶段必须拆分,不允许慢放/冻结
时间线估算规则
| 字段 | 计算方式 | 来源 |
|---|---|---|
| TTS 语速 | 固定 1.15x | qwen-tts.js 参数 rate: 1.15,不可修改 |
| 单 shot TTS 估算 | script.length ÷ 5(字/秒) |
AI 写入 duration 字段 |
| 视频模型固定时长 | Kling=6s, VEO=8s, Grok=6s | pipeline.js init 从 videoModel 推算 |
| ratio | estimatedVideoDuration / estimatedAudioDuration |
估算值,供分镜阶段检查 |
| ratio(实测) | videoDuration / audioDuration |
assemble 阶段真实值 |
图片模式(images)
图片没有独立时长。TTS 音频时长 = 画面时长。无 TTS 音频的 item 时长为 0(跳过,不显示)。
视频模式(videos)
铁律:视频片段必须 ≥ 音频片段。
TTS 音频为主轴,视频通过以下策略适配音频实测时长:
| ratio = estimatedVideoDuration / estimatedAudioDuration | 策略 | 说明 |
|---|---|---|
| 0.9 ~ 1.1 | none | 接近匹配,无需调整 |
| > 1.1, ≤ 2 | speed_up(最优) | 视频加速追上音频,音频速率不变 |
| > 2 | trim(次选) | 视频截断至音频时长,损失尾部 |
| < 0.9 | 禁止 / 打回分镜 | audioDur > videoDur 的 shot 在分镜阶段必须拆分,不允许慢放/冻结 |
禁止的策略(已删除):
slow_down:音频时长超过视频时不允许慢放freeze:不允许冻结帧补齐- 音频调速:CapCut 导入音频时无 speed 字段,1.15x 速率固定
所有策略失败后兜底:截断到目标时长。