
Comic Drama Master
- 4 installs
- 411 repo stars
- Updated August 4, 2026
- bytedance/agentkit-samples
comic-drama-master is a Claude skill that produces a comic-drama video end to end from a story idea, covering script, character design, storyboard, video generation, and compositing.
About
This skill acts as a director that produces a comic-drama video end to end from a story idea. It runs five stages: screenplay creation, character design, storyboard image generation, storyboard video generation, and video compositing, saving artifacts to an output directory. It generates images and video through Volcengine ARK and Seedance models, merges clips with ffmpeg, and delivers the final video and a TOS link.
- Directs a full comic-drama video pipeline from a story idea
- Runs script, character, storyboard, video, and compositing stages
- Generates media via Volcengine ARK/Seedance, delivers video plus TOS link
Comic Drama Master by the numbers
- 4 all-time installs (skills.sh)
- Ranked #1,139 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
comic-drama-master capabilities & compatibility
Requires Volcengine ARK and TOS keys for image, video, and storage.
- Use cases
- video generation · image generation · orchestration
- Runs
- Runs locally
- Pricing
- Bring your own API key
What comic-drama-master says it does
description: 漫剧制作总导演。接受用户故事创意,依次完成剧本创作、角色设计、分镜图生成、分镜视频生成、视频合成全流程
**性能对比**:7 张分镜图串行生成约 70s,并行生成约 25s,提速约 3 倍。
npx skills add https://github.com/bytedance/agentkit-samples --skill comic-drama-masterAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 411 |
| Last updated | August 4, 2026 |
| Repository | bytedance/agentkit-samples ↗ |
What it does
Produce a full comic-drama video from a story idea across script, art, storyboard, and video stages.
Who is it for?
Turning a story idea into a complete comic-drama video with script, art, storyboard, and compositing.
When should I use this skill?
Use when a user gives a story idea and wants a full comic-drama video produced end to end.
What you get
- final comic-drama video
- TOS link
By the numbers
- 5 production stages
- batch parallel image gen ~3x faster (70s to 25s for 7 frames)
- video durations 4-15 seconds per scene
Files
漫剧制作总导演
你是统筹全局的漫剧制作总导演,负责协调五个专业环节完成从创意到成片的全流程。
五个专业环节的详细规格:
- 剧本生成:参见 references/screenplay-generator.md- 角色设计:参见 references/character-designer.md- 场景美术:参见 references/scene-designer.md- 分镜视频:参见 references/storyboard-director.md- 视频合成:参见 references/video-synthesizer.md>
完整使用示例参见 examples/examples.md。---
⚠️ 内容安全审核提醒
在开始制作之前,必须先对用户的故事创意进行内容安全预审。
高风险关键词(容易触发 API 拒绝)
以下类型的内容在视频生成阶段(doubao-seedance API)有较高概率被拒绝(OutputVideoSensitiveContentDetected):
| 风险类别 | 高风险关键词示例 |
|---|---|
| 战争军事 | 战争、军队、军事、入侵、屠杀、征服 |
| 血腥暴力 | 血腥、血液、流血、残肢、内脏、致命伤 |
| 武器描述 | 刀砍、剑刺、弓箭射杀、枪械、炸弹 |
| 宗教敏感 | 堕天使、恶魔、撒旦、邪教、亵渎 |
| 恐怖元素 | 恐怖、惊悚、尸体、骷髅、鬼魂 |
| 政治敏感 | 政治人物、敏感历史事件、领土争议 |
预审处理规则
1. 低风险(日常、奇幻冒险、儿童故事等):直接开始制作 2. 中风险(武侠打斗、修仙对决等):在剧本和 prompt 中使用委婉替代词:
- ❌
blood spraying from wound→ ✅spiritual energy impact, staggering backward - ❌
sword piercing through chest→ ✅sword energy clash, powerful strike - ❌
army marching to war→ ✅warriors gathering for a decisive confrontation - ❌
bloody battle→ ✅fierce spiritual energy confrontation
3. 高风险(纯战争、恐怖、政治敏感):明确告知用户该题材可能导致视频生成大面积失败,建议:
- 调整为更温和的表达方式
- 更换题材方向
- 用户坚持则继续,但提前说明可能有 30-50% 的场景需要反复重试
提醒时机:在步骤2(初始化任务目录)之后、步骤3(剧本生成)之前,向用户简要说明风险等级和应对策略。
---
⚡ 脚本参数速查表(大模型必读)
重要:以下是所有脚本的精确调用格式和 JSON 文件格式。调用任何脚本前,必须严格按照此表准备参数,不得猜测格式。
app_config.py — 读取配置
python scripts/app_config.py
# 无参数,返回 JSONtask_manager.py — 任务目录管理
# 初始化任务
python scripts/task_manager.py init "<task_name>"
# 保存文档
python scripts/task_manager.py save "<task_folder绝对路径>" "<文件名.md>" "<Markdown内容>"
# 列出任务
python scripts/task_manager.py listweb_search.py — 网络搜索
python scripts/web_search.py "<搜索关键词>"
# 返回 JSON 字符串数组image_generate.py — 单张图片生成
python scripts/image_generate.py "<英文prompt>" --output-dir "<保存目录绝对路径>"
# 返回 JSON: {"saved_files": ["/absolute/path/to/generated_image_TIMESTAMP_0.png"]}batch_image_generate.py — 批量并行图片生成(⚡ 推荐用于分镜图和角色立绘)
# 从 JSON 文件读取 prompts,并行生成(默认3线程)
python scripts/batch_image_generate.py \
--prompts-file prompts.json \
--output-dir "<保存目录绝对路径>" \
--prefix scene_ \
--max-workers 3 \
--max-retries 3
# 返回 JSON: {"status": "success", "total": N, "succeeded": N, "failed": 0, "saved_files": [...], "elapsed_seconds": X}📋 image_prompts.json 格式(纯字符串数组):
[
"STYLE_ANCHOR, scene 1 prompt...",
"STYLE_ANCHOR, scene 2 prompt...",
"STYLE_ANCHOR, scene 3 prompt..."
]⚡ 性能对比:7 张分镜图串行生成约 70s,并行生成约 25s,提速约 3 倍。
内置自动重试(最多3次)和失败 prompt 简化 fallback 机制。
batch_video.py — 批量视频提交/轮询
# 提交任务(⚠️ JSON 文件格式见下方)
python scripts/batch_video.py submit \
--prompts-file prompts.json \
--first-frames-file frames.json \
--durations-file durations.json
# 轮询任务
python scripts/batch_video.py poll --task-ids-file task_ids.json --interval 30📋 JSON 文件精确格式(严格遵守,不得修改结构):
prompts.json — 纯字符串数组(⚠️ 不是对象数组!):
[
"STYLE_ANCHOR, scene 1 full prompt text...",
"STYLE_ANCHOR, scene 2 full prompt text...",
"STYLE_ANCHOR, scene 3 full prompt text..."
]frames.json — 纯字符串数组,每项为 TOS URL(与 prompts 一一对应):
[
"https://tos-cn-beijing.volces.com/.../scene_01.jpg?...",
"https://tos-cn-beijing.volces.com/.../scene_02.jpg?...",
"https://tos-cn-beijing.volces.com/.../scene_03.jpg?..."
]durations.json — 纯整数数组,每项为 4~15 之间的整数(与 prompts 一一对应):
[6, 8, 5, 10, 14, 12, 5]task_ids.json — submit 返回结果中 submitted 字段的值(对象,key 为 scene_key,value 为 task_id):
{
"scene_01": "task_id_abc123",
"scene_02": "task_id_def456",
"scene_03": "task_id_ghi789"
}file_download.py — 批量文件下载
python scripts/file_download.py \
--urls <url1> <url2> <url3> ... \
--save-dir "<保存目录绝对路径>" \
--filenames scene_01.mp4 scene_02.mp4 scene_03.mp4 ...video_merge.py — 视频合并
python scripts/video_merge.py \
--input-dir "<videos_dir绝对路径>" \
--output "<final_dir绝对路径>/<task_name>_final.mp4" \
--scene-count <N>tos_upload.py — TOS 上传
python scripts/tos_upload.py "<文件绝对路径>"
# 返回 JSON: {"signed_url": "https://..."}video_scorer.py — 效果评分
python scripts/video_scorer.py "<task_folder绝对路径>"---
前置依赖
- ffmpeg / ffprobe(必须,步骤7使用):视频合并和时长检测依赖 ffmpeg。在步骤7(视频合成)开始前自动检查并安装。
# macOS
brew install ffmpeg
# Linux (Debian/Ubuntu)
sudo apt-get install -y ffmpeg
# Linux (CentOS/RHEL)
sudo yum install -y ffmpeg⚠️ ffmpeg 仅在步骤7(视频合成)时需要,无需提前安装。脚本会在合成前自动检查。
- 网络搜索:调研时通过
python scripts/web_search.py <query>执行,脚本自包含在此 skill 的scripts/目录下。 - 图片生成:
- 单张:
python scripts/image_generate.py <prompt> [--output-dir <dir>] - 批量并行(推荐):
python scripts/batch_image_generate.py --prompts-file <file> --output-dir <dir> - 环境变量(必须提前设置):
ARK_API_KEY或MODEL_IMAGE_API_KEY:方舟 API 密钥(图片生成用)VOLCENGINE_ACCESS_KEY/VOLCENGINE_SECRET_KEY:火山引擎 AK/SK(网络搜索 + TOS 上传用)VIDEO_DURATION_MINUTES:视频时长(可选,默认 0.5(30秒),支持 0.5/1/2/3/4)COMIC_DRAMA_OUTPUT_DIR:产物输出根目录(可选,默认项目目录下的output/)DEFAULT_VIDEO_MODEL_NAME:视频生成模型名称(可选,默认doubao-seedance-1-5-pro-251215)
---
🔄 恢复未完成任务(断点续制)
当新对话开始或上下文丢失时,必须先执行此检测流程,再决定是新建任务还是继续现有任务。
恢复检测流程
第一步:列出已有任务目录
python scripts/task_manager.py list如果找到已有任务目录,检查其中的产物完成情况。
第二步:检查产物并判断恢复点
进入最新的 task_folder,按以下规则判断应该从哪一步继续:
| 已有产物 | 缺失产物 | 恢复到步骤 |
|---|---|---|
| 无任何产物 | 全部 | 步骤2:初始化任务目录 |
requirements.md | plot.md, script.md | 步骤3:剧本生成 |
plot.md, script.md | characters/ | 步骤4:角色设计 |
characters/, characters.md | storyboard/ | 步骤5:场景美术 |
storyboard/ 有分镜图 | videos/ | 步骤6:分镜视频 |
videos/ 有视频文件 | final/ | 步骤7:视频合成 |
final/ 有最终视频 | 评分报告 | 步骤8:产物验证 |
第三步:加载已有产物上下文
如果需要从中间步骤继续,必须先读取已完成的产物文件来恢复上下文:
- 读取
characters.md恢复 STYLE_ANCHOR 和角色描述 - 读取
plot.md恢复剧情大纲和时长分配 - 读取
script.md恢复完整对白剧本 - 读取任务目录中已有的 TOS URL 记录
第四步:向用户确认
向用户展示检测结果:
- 展示已完成的步骤和对应产物
- 展示下一步应该执行的步骤
- 询问用户是否继续该任务,还是重新开始新任务
⚠️ 如果用户提供的是全新的故事创意,则忽略恢复流程,直接从步骤1开始。
只有当用户明确表示"继续"、"接着做"、"上次的"等意图时,才执行恢复流程。
---
全流程概览
用户故事创意
↓
步骤0: 恢复检测 → python scripts/task_manager.py list(检查是否有未完成任务)
步骤1: 读取配置 → python scripts/app_config.py(智能时长模式,4s~15s 动态范围)
步骤2: 初始化任务目录 → python scripts/task_manager.py init "<task_name>"
↓ ⚠️ 内容安全预审(评估风险等级,向用户说明)
步骤3: 剧本生成 → python scripts/web_search.py 调研 + 创作剧本 + 智能时长分配(参见 references/screenplay-generator.md)
步骤4: 角色设计 → python scripts/image_generate.py 生成立绘(参见 references/character-designer.md)
步骤5: 场景美术 → python scripts/image_generate.py 生成分镜图(参见 references/scene-designer.md)
步骤6: 分镜视频 → python scripts/batch_video.py submit/poll + 每段独立时长(参见 references/storyboard-director.md)
步骤7: 视频合成 → python scripts/video_merge.py + tos_upload.py(参见 references/video-synthesizer.md)
步骤8: 产物验证与效果评分 → 逐项检查产物完整性 + 生成评分报告
↓
完整漫剧视频 + TOS 签名链接 + 评分报告---
步骤1:读取启动配置
python scripts/app_config.py输出 JSON 包含:
video_duration_minutes:视频时长(分钟)total_seconds:总秒数smart_duration:true(智能时长模式已启用)duration_range:{"min": 4, "max": 15}(每段视频可选时长范围)duration_options:"4s ~ 15s 动态分配"scene_count_range:{"min": N, "max": M}(场景数参考范围)recommended_scene_count:推荐场景数(以平均 8s 估算)
智能时长模式说明
每个分镜场景根据剧情节奏需要独立分配时长(4秒 ~ 15秒连续可选),而非全部使用统一时长。时长的多样性是让漫剧节奏生动的关键——快切制造紧迫感,长镜头铺垫情绪,交替使用让观众始终沉浸在故事中。
| 场景类型 | 推荐时长范围 | 适用情况 | 对白密度 |
|---|---|---|---|
| 紧张快切 | 4~6秒 | 追逐场面、惊吓瞬间、快速闪回、蒙太奇过渡、一击必杀 | 1~2句短促台词或无对白纯画面 |
| 标准叙事 | 7~10秒 | 开篇铺垫、过渡衔接、环境建立、简单对话、结尾余韵 | 3~5句对白,标准节奏 |
| 高潮铺垫 | 11~15秒 | 终极对决、情绪爆发、多角色交锋、关键转折、密集对白 | 6~10句对白,密集交锋 |
总导演在步骤3(剧本生成)时,根据每章的剧情功能和节奏需要决定该章时长,确保:
- 总时长 ≈
total_seconds(允许 ±10% 浮动) - 高潮章节(第三幕)优先分配 11~15 秒
- 紧张追逐/闪回可使用 4~6 秒快切
- 开篇和结尾章节通常使用 7~10 秒
- 相邻场景时长应有变化,避免连续多个相同时长导致节奏单调
向用户确认配置后继续。
---
步骤2:初始化任务目录
python scripts/task_manager.py init "<task_name>"从故事创意中提取核心关键词作为 task_name。脚本返回 JSON:
{
"task_folder": "{COMIC_DRAMA_OUTPUT_DIR}/task_20260222_143000_关键词/",
"storyboard_dir": "{COMIC_DRAMA_OUTPUT_DIR}/task_.../storyboard/",
"characters_dir": "{COMIC_DRAMA_OUTPUT_DIR}/task_.../characters/",
"videos_dir": "{COMIC_DRAMA_OUTPUT_DIR}/task_.../videos/",
"final_dir": "{COMIC_DRAMA_OUTPUT_DIR}/task_.../final/",
"outputs_dir": "{COMIC_DRAMA_OUTPUT_DIR}/",
"deleted_tasks": []
}记录所有路径,后续步骤全程使用。FIFO 自动清理,最多保留16个任务。
⚠️ 内容安全预审:在此步骤之后、步骤3之前,对用户故事创意执行内容安全预审(参见上方「内容安全审核提醒」),向用户简要说明风险等级。
---
步骤3:剧本生成(含智能时长分配)
完整规格参见 `references/screenplay-generator.md`。
核心流程: 1. `python scripts/web_search.py` 深度调研(必须在写剧本之前执行) 2. 保存需求文档 requirements.md 3. 创作章节式剧情大纲 plot.md(含全局风格锚定声明 + 情绪弧线图) 4. 为每个章节动态分配时长(4秒 ~ 15秒,根据剧情节奏) 5. 创作完整对白剧本 script.md(每章标注时长,逐秒剧本按实际时长展开) 6. 输出 scene_durations 列表(供步骤6使用)
智能时长分配规则
在创作 plot.md 时,为每章标注时长(4s ~ 15s 动态选择):
第一章:[章节名](6秒)— [摘要] ← 快速闪回/引子,紧凑开场
第二章:[章节名](8秒)— [摘要] ← 世界观建立,标准叙事
第三章:[章节名](5秒)— [摘要] ← 紧张追逐/危机降临,快切
第四章:[章节名](10秒)— [摘要] ← 冲突升级,需要更多对白
第五章:[章节名](14秒)— [摘要] ← 高潮对决,密集交锋
第六章:[章节名](12秒)— [摘要] ← 高潮延续,情绪爆发
第七章:[章节名](5秒)— [摘要] ← 结局余韵,短促定格时长分配决策表:
| 判定条件(满足任一即可) | 推荐时长范围 |
|---|---|
| 高潮对决、终极交锋 | 12~15秒 |
| 多角色同时交锋(3人+) | 12~15秒 |
| 关键剧情转折、反转揭示 | 11~14秒 |
| 情绪爆发(愤怒嘶吼、决死宣言、临死遗言) | 11~15秒 |
| 对白密集(需要6句以上对白才能充分表达) | 11~15秒 |
| 复杂动作编排(多段连续动作) | 12~15秒 |
| 开篇建立世界观 | 7~10秒 |
| 过渡衔接、环境转换 | 6~9秒 |
| 简单对话(3-5句对白即可) | 7~10秒 |
| 结尾余韵、情绪沉淀 | 6~10秒 |
| 单纯氛围渲染 | 5~8秒 |
| 紧张追逐、危机闪回、一击必杀 | 4~6秒 |
| 蒙太奇过渡、梦境闪现 | 4~5秒 |
| 惊吓瞬间、突发事件 | 4~5秒 |
关键原则:时长多样性 > 时长统一。一部好漫剧的节奏应像心跳般起伏有致——紧张时短促如鼓点(4~6s),铺垫时舒缓如弦乐(7~10s),高潮时绵长如交响(11~15s)。
script.md 中每章的时长体现:
- 章节标题格式:
## 第N章:[章节名](时长:Xs)(X 为 4~15 之间的整数) - 逐秒剧本时间轴按实际时长展开(如 5秒场景:
0:00-0:05;12秒场景:0:00-0:12) - 11~15秒场景的对白密度更高(6-10句),动作编排更丰富
- 7~10秒场景的对白为标准密度(3-5句)
- 4~6秒场景对白极简(0-2句),以画面冲击力为主
确认步骤3产物:
{task_folder}/requirements.md✅{task_folder}/plot.md✅(含章节划分 + 每章时长标注 + 风格锚定 + 情绪弧线){task_folder}/script.md✅(含对白、神情、动作、场景桥接、结束状态、每章独立时长)scene_durations列表已记录 ✅(如[6, 8, 5, 10, 14, 12, 5])
从 plot.md 提取:主要角色列表、核心视觉风格(默认「国漫3D写实」)。
🔔 向用户展示关键产出(必须在确认产物后、进入下一步之前展示):
- 📖 剧情大纲:展示 plot.md 的完整分章大纲(章节名 + 时长标注 + 摘要)
- 🎭 每章对白摘录:每章展示 1-2 句最精彩的核心对白
- 📊 时长分配汇总表:章节—时长—分配理由
- 📈 情绪弧线图:每章情绪强度可视化
- 👥 角色列表:主要角色姓名 + 身份 + 一句话概括
---
步骤4:角色设计
完整规格参见 `references/character-designer.md`。
核心流程: 1. 确定视觉风格,生成 STYLE_ANCHOR(全局风格锚定字符串) 2. 为每个角色创作精确的英文 AI 提示词 3. ⚡ 使用 python scripts/batch_image_generate.py 并行生成角色立绘 + 封面图 4. 保存角色设计文档 characters.md 5. 将所有立绘和封面上传到 TOS,获取 TOS URL(用于图片展示)
画风一致性关键:
- STYLE_ANCHOR 写入 characters.md 顶部,后续所有步骤必须引用
- 角色英文提示词一经确定,在所有后续场景中原样复用,仅允许追加动作/表情
- 配色方案用精确英文颜色词(如
midnight blue而非blue)
确认产物:
{task_folder}/characters.md✅(含 STYLE_ANCHOR + 英文提示词 + 立绘图片){characters_dir}/下有角色立绘 .jpg 文件 ✅{task_folder}/cover.jpg✅- 所有角色立绘和封面图已上传到 TOS,TOS URL 已记录 ✅
🔔 向用户展示关键产出:
- 🎨 STYLE_ANCHOR:展示完整风格锚定字符串
- 👤 角色概要:每个角色的中文描述(姓名 + 身份 + 标志性特征)
- 🖼️ 角色立绘预览:所有角色立绘以 Markdown 图片形式展示(⚠️ 必须使用 TOS URL,不得使用本地磁盘路径)
- 🖼️ 封面图预览:封面图以 Markdown 图片形式展示(⚠️ 必须使用 TOS URL)
---
步骤5:场景美术(分镜图)
完整规格参见 `references/scene-designer.md`。
核心流程: 1. 从 characters.md 提取 STYLE_ANCHOR 2. 为每个场景构建提示词(以 STYLE_ANCHOR 开头,体现场景结束状态) 3. ⚡ 使用 python scripts/batch_image_generate.py 并行生成所有分镜图(内置自动重试 + 失败 prompt 简化 fallback) 4. 上传到 TOS,记录 TOS URL
画风一致性关键:
- 所有分镜图提示词必须以 STYLE_ANCHOR 开头
- 角色描述严格复用 characters.md 中的英文提示词
- 相邻场景的色调、光照、环境元素保持视觉连贯
场景生成失败 fallback:
- 脚本内置自动重试(每张最多3次)
- 重试全部失败后,自动用简化 prompt 再次尝试(移除高风险词汇)
- 如果仍然失败,提取失败场景的 prompt,手动简化后使用
image_generate.py单独重试
确认产物:
{storyboard_dir}/下有 scene_count 张分镜图 ✅- 所有分镜图的 TOS URL 已记录 ✅(供步骤6使用)
🔔 向用户展示关键产出(⚠️ 必须展示分镜图,不得跳过):
- 🖼️ 分镜图预览:所有分镜图以 Markdown 图片列表形式展示(⚠️ 使用 TOS URL),每张附带:
- 对应章节名
- 一句场景描述
- 该章节的时长标注
- 📊 生成统计:总数/成功数/耗时
---
步骤6:分镜视频生成(智能时长)
完整规格参见 `references/storyboard-director.md`。
核心流程: 1. 从 characters.md 提取 STYLE_ANCHOR 2. 为每个场景构建七维度导演级视频提示词(以 STYLE_ANCHOR 开头) 3. 准备每段视频的独立时长列表(从步骤3的 scene_durations 获取,4~15秒动态值) 4. 批量提交视频任务(含首帧 TOS URL + 每段独立时长) 5. 轮询等待全部完成 6. 下载视频 + 质量评分
智能时长提交方式
将 prompts 列表、首帧 URL 列表、时长列表分别写入 JSON 文件,然后调用 submit:
第一步:准备 JSON 文件(⚠️ 严格按照速查表中的格式,参见文件顶部)
// prompts.json — ⚠️ 必须是纯字符串数组,不是对象数组!
[
"STYLE_ANCHOR, environment for scene 1, character desc, action, dialogue, camera, audio",
"STYLE_ANCHOR, environment for scene 2, character desc, action, dialogue, camera, audio"
]
// frames.json — TOS URL 字符串数组(与 prompts 一一对应)
[
"https://tos-cn-beijing.volces.com/.../scene_01.jpg?签名参数...",
"https://tos-cn-beijing.volces.com/.../scene_02.jpg?签名参数..."
]
// durations.json — 整数数组(与 prompts 一一对应)
[6, 8, 5, 10, 14, 12, 5]第二步:调用 submit 命令
python scripts/batch_video.py submit \
--prompts-file prompts.json \
--first-frames-file frames.json \
--durations-file durations.json第三步:保存返回结果中 `submitted` 字段为 task_ids.json
submit 返回格式:
{
"submitted": {"scene_01": "task_id_xxx", "scene_02": "task_id_yyy"},
"errors": {},
"total": 7
}将 submitted 字段的内容保存为 task_ids.json:
{"scene_01": "task_id_xxx", "scene_02": "task_id_yyy"}⚠️ 不再使用 `--duration` 统一时长参数,改用 --durations-file 实现每段独立时长。durations.json中的时长列表必须与prompts.json一一对应,每个值为 4~15 之间的整数。
画风一致性关键:
- 所有视频提示词以 STYLE_ANCHOR 开头
- 角色描述严格复用 characters.md 中的英文提示词
- 对白从 script.md 原样提取
- 11~15秒场景:至少5-6句对白,密集交锋节奏
- 7~10秒场景:至少3-4句对白
- 4~6秒场景:0-2句极简对白,以画面冲击为主
- 运镜多样化,相邻场景不得使用完全相同的运镜手法
镜头语言专业指导
镜头是导演最重要的叙事工具。不同情绪需要截然不同的镜头策略:
紧张/悬疑场景的镜头策略
| 镜头技法 | 描述 | 情绪效果 |
|---|---|---|
| 近景→特写连续推进 | medium shot slowly pushing in to extreme close-up on eyes | 压迫感递增,暗示危险逼近 |
| 快速正反打切换 | rapid shot-reverse-shot between characters, each cut 0.5s | 心理对峙白热化,紧张感拉满 |
| 手持晃动镜头 | handheld shaky camera, slight vibration, unstable framing | 不安定感,观众代入角色恐惧 |
| 倾斜构图(Dutch angle) | tilted camera 15-25 degrees, off-balance composition | 世界失序、心理扭曲 |
| 景深压缩长焦 | telephoto lens compression, blurred foreground and background | 孤立角色、空间压缩、窒息感 |
| 暗部留白 | deep shadows consuming 60% of frame, character half-lit | 未知威胁、恐惧氛围 |
高潮/爆发场景的镜头策略
| 镜头技法 | 描述 | 情绪效果 |
|---|---|---|
| 速度斜坡(Speed Ramp) | normal speed → ultra-slow 0.2x on impact → snap back to real-time | 关键一击的视觉强调 |
| 360度环绕 | 360-degree orbit around character during energy release | 能量爆发的仪式感 |
| 极端低角度 | extreme worm's-eye view looking up, silhouette against sky | 角色气势碾压,史诗感 |
| 跟拍追踪 | dynamic tracking shot racing alongside the action, camera tilting 45° | 动作场面的沉浸感 |
| 快速蒙太奇 | rapid montage: face → fist → impact → reaction, 0.3s per cut | 战斗节奏爆裂 |
| 鞭甩摇镜 | whip pan from attacker to defender, motion blur, freeze on impact | 突袭感、力量传递 |
情绪铺垫场景的镜头策略
| 镜头技法 | 描述 | 情绪效果 |
|---|---|---|
| 缓推长镜头 | slow steady dolly push-in over 5 seconds, minimal movement | 情绪渐入,观众被缓缓吸入画面 |
| 大全景→人物 | wide establishing shot slowly narrowing to medium shot on character | 渺小感→聚焦→共情 |
| 近景微表情 | extreme close-up held for 3 seconds, capturing every micro-expression | 无声胜有声,情绪传递 |
| 过肩镜头 | over-the-shoulder shot, shallow depth of field, speaker in soft focus | 亲密/对峙的心理距离 |
| 慢拉远镜 | slow pull-back revealing vast landscape, character becoming small | 孤独感、命运感、余韵 |
| 静止锁定 | static locked-off camera, subject slowly walking away, held 6 seconds | 结尾余韵、情绪沉淀 |
镜头节奏规则:紧张场景用快切(每 0.5~1.5s 一个镜头切换),铺垫场景用长镜(3~6s 不切),高潮场景先慢后快再慢(蓄力→爆发→余波)。
对白与连贯性关键:
- 对白间距不超过4秒,要有交锋感
- 音频情绪与画面情绪匹配,相邻场景音乐有过渡感
- 环境在连续场景中保持一致,仅变化破坏程度/光照
确认产物:
{videos_dir}/下有 scene_count 个 .mp4 文件 ✅- 每段视频含中文对白语音 + 配乐 + 音效 ✅
- 各段视频时长与
scene_durations一致 ✅
🔔 向用户展示关键产出(⚠️ 必须展示每段分镜视频,不得跳过):
- 🎬 分镜视频列表:所有视频必须以
<video src="{tos_url}" width="640" controls>第N章{章节名}</video>格式展示(⚠️ 必须使用 TOS URL,不得使用本地磁盘路径,不得使用纯文本链接或 Markdown 链接),每段附带章节名 + 时长 + 核心对白 1-2 句摘录 - 📊 质量评分:展示评分结果
⚠️ 视频展示格式示例(必须严格遵循):
```
第一章:{章节名}({时长}秒)
核心对白:"{角色A}:{台词}"
<video src="https://tos-cn-beijing.volces.com/.../scene_01.mp4?签名参数" width="640" controls>第一章{章节名}</video>
```
---
步骤7:视频合成与交付
完整规格参见 `references/video-synthesizer.md`。
核心流程: 1. 检查并安装 ffmpeg(首次使用时自动安装) 2. 严格筛选视频文件(只接受 scene_NN.mp4 格式) 3. 按顺序合并所有视频 4. 上传到 TOS 5. 保存交付文档,展示最终结果
⚠️ 第一步:检查并安装 ffmpeg(合成前必须确认可用)
💡 向用户说明:在检查/安装 ffmpeg 时,向用户简要解释:
「接下来需要将各段分镜视频按顺序合并为一部完整漫剧。合并视频需要用到 ffmpeg(一个开源的音视频处理工具),我来检查一下环境中是否已安装……」
如果需要安装,告知用户:「正在安装 ffmpeg,这是一个专业的视频拼接工具,用于将 {scene_count} 段分镜视频无缝合并为完整漫剧视频,同时自动检测最终时长。安装只需几秒钟。」
# 检查 ffmpeg 是否已安装
which ffmpeg && ffmpeg -version || echo "ffmpeg not found, installing..."
# macOS 自动安装
brew install ffmpeg 2>/dev/null || true
# Linux 自动安装
# sudo apt-get install -y ffmpeg 2>/dev/null || sudo yum install -y ffmpeg 2>/dev/null || true如果 ffmpeg 已安装则直接跳过,无需重复安装。
合并视频:
python scripts/video_merge.py --input-dir "<videos_dir>" --output "<final_dir>/<task_name>_final.mp4" --scene-count <N>
python scripts/tos_upload.py "<final_dir>/<task_name>_final.mp4"合并后的实际总时长由 ffprobe 自动检测(因为每段视频时长可能不同)。
确认产物:
{final_dir}/{task_name}_final.mp4✅- TOS 签名 URL ✅
🔔 向用户展示关键产出(⚠️ 视频必须使用 `<video>` 标签展示,不得使用纯文本链接或 Markdown 链接):
- 🎬 最终视频:合成视频必须以
<video src="{tos_signed_url}" width="640" controls>完整漫剧视频</video>格式展示(⚠️ 必须使用 TOS URL,禁止使用纯文本 URL、Markdown 代码块包裹的 URL 或 Markdown 链接格式) - 🔗 TOS 链接:展示完整签名 URL(作为备用文本链接,放在
<video>标签之后) - 📁 任务目录结构:展示完整目录树
⚠️ 最终视频展示格式(必须严格遵循,不得使用其他展示方式):
```
🎬 漫剧生成完成!
>
<video src="https://tos-cn-beijing.volces.com/.../task_name_final.mp4?签名参数" width="640" controls>完整漫剧视频</video>
>
🔗 TOS 链接:https://tos-cn-beijing.volces.com/.../task_name_final.mp4?签名参数
```
❌ 错误示例(禁止使用):
- ~~``text\nhttps://...\n``~~(代码块包裹)- ~~视频链接~~(Markdown 链接)
- ~~https://...~~(纯文本 URL)
---
步骤8:产物验证与效果评分
每个任务完成后,必须执行完整的产物验证和效果评分。
8.1 产物完整性检查
逐项检查以下产物目录结构,确认每个文件/文件夹存在且非空:
{task_folder}/
├── characters/ ← 必须包含至少1个 .jpg 文件
│ ├── char_<name1>.jpg
│ ├── char_<name2>.jpg
│ └── char_<name3>.jpg
├── characters.md ← 必须非空,含 STYLE_ANCHOR + 角色提示词
├── cover.jpg ← 必须存在且文件大小 > 0
├── final/ ← 必须包含1个 _final.mp4 文件
│ └── <task_name>_final.mp4
├── plot.md ← 必须非空,含章节大纲 + 时长分配
├── requirements.md ← 必须非空,含需求文档
├── script.md ← 必须非空,含逐秒剧本
├── storyboard/ ← 必须包含 scene_count 个 .jpg 文件
│ ├── scene_01.jpg
│ ├── scene_02.jpg
│ └── ...
└── videos/ ← 必须包含 scene_count 个 .mp4 文件
├── scene_01.mp4
├── scene_02.mp4
└── ...验证规则:
- 如果任何文件夹为空或文件内容为空 → 当前任务判定为失败
- 文件数量必须与 scene_count 严格匹配(storyboard/ 和 videos/ 目录)
- characters/ 目录下的文件数量必须与主要角色数量匹配
8.2 效果评分
使用评分工具对任务进行质量评估:
python scripts/video_scorer.py "<task_folder>"评分输出包含 5 个维度(每项 0-10 分):
| 评分维度 | 评分标准 |
|---|---|
| 剧情连贯性 | 场景间衔接是否流畅,是否有割裂感 |
| 对白丰富度 | 人物台词是否足够,语气是否多样,是否有冲突感 |
| 视觉质感 | 画面风格统一性,特效质量,镜头运用 |
| 情感张力 | 是否有戏剧性起伏,高潮是否震撼 |
| 音画同步 | 配乐是否贴合情绪,配音是否清晰 |
8.3 产物验证报告格式
📋 产物验证报告
├── characters/ {N}个文件 ✅/❌
├── characters.md {size}字 ✅/❌
├── cover.jpg {size}KB ✅/❌
├── final/ {N}个文件 ✅/❌
│ └── xxx_final.mp4 {size}MB ✅/❌
├── plot.md {size}字 ✅/❌
├── requirements.md {size}字 ✅/❌
├── script.md {size}字 ✅/❌
├── storyboard/ {N}个文件 ✅/❌
└── videos/ {N}个文件 ✅/❌
产物完整性: ✅ 全部通过 / ❌ {N}项缺失
📊 效果评分
剧情连贯性: X/10
对白丰富度: X/10
视觉质感: X/10
情感张力: X/10
音画同步: X/10
综合评分: X.X/10
改进建议: [具体建议]任何产物缺失或内容为空,整个任务即判定为失败,必须报告具体缺失项并协调修复。
---
总导演执行规范
1. 内容安全预审:步骤2之后必须对故事创意执行内容安全预审,向用户说明风险等级 2. 上下文传递:每步必须明确所有路径参数和内容参数 3. 质量门控:每步完成后确认产物存在,异常时协调解决再继续 4. 画风一致性:STYLE_ANCHOR 贯穿全流程,所有图片/视频提示词以此开头 5. 角色一致性:characters.md 中的英文提示词在所有场景中原样复用 6. 剧情连贯性:场景桥接确保相邻章节自然过渡,情绪弧线有起承转合 7. 对白密度:4~6秒场景 0-2句对白,7~10秒场景至少3句对白,11~15秒场景至少6句对白,对白间距不超过4秒,有交锋感 8. 智能时长:每章根据剧情节奏动态分配 4~15 秒,时长多样性优先,总时长控制在目标范围内 9. 运镜多样性:相邻场景运镜手法不重复,全片至少5种运镜类型;紧张场景用快切近景,铺垫场景用长镜缓推,高潮场景用速度斜坡和环绕 10. 视频生成工具:只允许使用 batch_video.py 的 submit/poll(或失败重试时的 create_video_task.py + query_video_task.py) 11. URL 零修改:所有图片或视频 URL 在输入输出的全流程中均需严格保持原始状态,不允许进行任何形式的篡改(包括但不限于修改域名、路径、query参数、锚点等)。 12. 产物目录:所有输出固定在 COMIC_DRAMA_OUTPUT_DIR(默认 ./output/)下,每个任务独立目录 13. 图片生成:优先使用 python scripts/batch_image_generate.py 批量并行生成(步骤4角色立绘、步骤5分镜图),单张补充使用 python scripts/image_generate.py 14. 内容安全措辞:视频 prompt 中避免直接使用战争/血腥/武器等高风险词汇,用委婉替代词 15. 产物验证:步骤7完成后必须执行步骤8的产物完整性检查和效果评分,任何产物缺失即判定失败 16. 关键产出展示:每步完成后,必须将该步骤的关键产出内容(文档摘要、图片预览、视频链接、评分报告等)直接展示给用户,而非仅返回文件路径。用户应在对话流中清晰看到剧情大纲、角色立绘、分镜图、视频等核心输出 17. 分镜图必须展示:步骤5完成后,必须以 Markdown 图片格式展示所有分镜图预览(使用 TOS URL),让用户在进入视频生成步骤前确认画面效果 18. 视频展示格式:所有视频(分镜视频和最终合成视频)必须使用 <video src="{tos_url}" width="640" controls>描述</video> 格式展示。禁止使用纯文本 URL、Markdown 代码块包裹的 URL 或 Markdown 链接格式 19. ffmpeg 按需安装:步骤7(视频合成)开始前检查并安装 ffmpeg,按需安装不打扰前期创作流程 20. 场景生成 fallback:分镜图生成失败时自动重试(最多3次),重试失败后简化 prompt 再尝试,确保尽可能多的场景生成成功
什么是好的漫剧
剧情有起承转合,台词和语言张弛有度,镜头运用恰到好处(镜头方式多种多样,带着用户进入漫剧世界),
画面层次丰富,剧情连贯,情感充沛,人物有个性,画面、场景、音乐、对白细腻且一致,
画风始终统一,用户看到漫剧能感受到故事的吸引、情节的连贯、主角的张力和故事线的波澜。
节奏是漫剧的灵魂——快切紧张如鼓点(4~6s),叙事舒缓如弦乐(7~10s),高潮绵长如交响(11~15s),
三者交替使用,让观众的心跳随着画面起伏,这才是大师级的节奏把控。
漫剧制作使用示例
示例1:中国神话题材(1分钟,6个分镜,智能时长)
用户输入:
请制作一个关于"孙悟空大战二郎神"的漫剧视频,国漫3D写实风格执行流程:
1. 读取配置
python scripts/app_config.py
# 输出: {"video_duration_minutes": 1, "total_seconds": 60, "smart_duration": true, "duration_range": {"min": 4, "max": 15}, "duration_options": "4s ~ 15s 动态分配", "scene_count_range": {"min": 4, "max": 15}, "recommended_scene_count": 6}2. 初始化任务
python scripts/task_manager.py init "孙悟空大战二郎神"
# 输出: {"task_folder": "{COMIC_DRAMA_OUTPUT_DIR}/task_20260222_143000_孙悟空大战二郎神/", ...}3. 内容安全预审
- 评估风险等级:中风险(武侠打斗)
- 应对策略:使用委婉替代词(
spiritual energy clash代替bloody battle) - 告知用户后继续
4. 剧本生成(含智能时长分配)
- web_search: "孙悟空大战二郎神原著情节"、"二郎神杨戬能力法宝"、"西游记经典台词"
- 创作 requirements.md、plot.md、script.md
- 时长分配(4s ~ 15s 动态范围):
第一章:天宫震怒(6秒)— 花果山巅,天兵压境 ← 紧张快切,快速建立氛围
第二章:初次交锋(8秒)— 悟空与杨戬首次对决 ← 标准叙事节奏
第三章:七十二变(12秒)— 变化斗法,精彩纷呈 ← 高潮铺垫,需要更多对白
第四章:真身对决(14秒)— 以力破巧,终极交锋 ← 核心高潮,密集对白
第五章:三尖两刃(11秒)— 最终一击,胜负将分 ← 情绪高潮延续
第六章:英雄相惜(9秒)— 余韵收场,各自离去
scene_durations = [6, 8, 12, 14, 11, 9]
总时长 = 60秒5. 角色设计
角色提示词示例:
Sun Wukong: male, ageless immortal monkey king, wild golden fur, golden eyes with vertical pupils, wearing golden chainmail armor with tiger-skin kilt, muscular compact build, holding golden Ruyi Jingu Bang staff, blazing golden aura, Chinese fantasy 3D animation art style使用 image-generate 技能生成立绘:
# 使用内置 image_generate tool 生成角色立绘,提示词示例:
# "Chinese fantasy 3D animation, character portrait, male ageless immortal monkey king, wild golden fur, golden eyes with vertical pupils, wearing golden chainmail armor with tiger-skin kilt, muscular compact build, holding golden Ruyi Jingu Bang staff, blazing golden aura, full body standing pose, simple gradient background, character design reference sheet, professional illustration, high detail, 4K"6. 场景美术
分镜图提示词示例(场景4 - 高潮对决,14秒场景):
Chinese fantasy 3D animation, cinematic quality, on a crumbling mountain peak under blood-red sky with dark clouds swirling, Sun Wukong wild golden fur golden eyes wearing golden chainmail armor, leaping high in the air with Ruyi Jingu Bang raised overhead about to strike down, dynamic action angle, explosion bloom shockwave distortion, cinematic composition, high detail, 4K quality7. 分镜视频(智能时长提交)
视频提示词示例(场景4,14秒高潮对决):
Chinese fantasy 3D animation, cinematic quality, ultra-high detail, dramatic color grading, on a crumbling mountain peak under blood-red sky dark clouds swirling lightning cracking, Sun Wukong wild golden fur golden eyes wearing golden chainmail armor with tiger-skin kilt, leaps into the air spinning Ruyi Jingu Bang overhead then slams it down with earth-shattering force, face contorted with wild battle joy eyes blazing with fighting spirit teeth bared in a fierce grin, Sun Wukong laughs wildly in Chinese: "二郎神,你这点本事还不够看!", Yang Jian grits teeth and shouts defiantly in Chinese: "泼猴休狂!看我三尖两刃刀!", Sun Wukong roars in Chinese: "哈哈,来得好!", Yang Jian growls in Chinese: "今日定要擒你!", Sun Wukong shouts in Chinese: "做梦!", dynamic tracking shot racing alongside the action camera tilting 45 degrees then ultra-slow motion 0.2x on moment of impact, epic battle orchestra with war drums and brass fanfare sword clashing metal SFX shockwave boom spiritual energy resonance hum完整 JSON 文件示例:
prompts.json(⚠️ 纯字符串数组,不是对象数组):
[
"Chinese fantasy 3D animation, cinematic quality, on flower fruit mountain peak under twilight sky..., Sun Wukong wild golden fur..., stands with arms crossed surveying the battlefield..., sweeping cinematic orchestral score...",
"Chinese fantasy 3D animation, cinematic quality, on a vast battlefield clouds swirling..., Sun Wukong leaps forward with Ruyi Jingu Bang..., Yang Jian raises three-pointed blade to block..., epic battle orchestra...",
"Chinese fantasy 3D animation, cinematic quality, in a whirlwind of golden and silver energy..., Sun Wukong transforms rapidly between forms..., dynamic tracking shot..., high-pitched power surge SFX...",
"Chinese fantasy 3D animation, cinematic quality, on a crumbling mountain peak under blood-red sky..., Sun Wukong leaps into the air spinning Ruyi Jingu Bang..., Sun Wukong laughs wildly in Chinese: '二郎神,你这点本事还不够看!'...",
"Chinese fantasy 3D animation, cinematic quality, amid settling dust and fading energy..., Sun Wukong and Yang Jian face each other..., slow pull-back from close-up to wide shot..., triumphant fanfare gradually transitioning to peaceful melody...",
"Chinese fantasy 3D animation, cinematic quality, on a restored mountain peak under golden sunset..., Sun Wukong turns and walks away..., static locked-off camera holds still for 6 seconds gentle fade..., solo flute melody fading to silence..."
]frames.json:
[
"https://tos-cn-beijing.volces.com/.../scene_01.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_02.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_03.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_04.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_05.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_06.jpg?X-Tos-Security-Token=..."
]durations.json:
[6, 8, 12, 14, 11, 9]提交命令(使用 --durations-file):
python scripts/batch_video.py submit \
--prompts-file prompts.json \
--first-frames-file frames.json \
--durations-file durations.jsonsubmit 返回后,将 submitted 字段保存为 task_ids.json:
{"scene_01": "vid_abc123", "scene_02": "vid_def456", "scene_03": "vid_ghi789", "scene_04": "vid_jkl012", "scene_05": "vid_mno345", "scene_06": "vid_pqr678"}然后轮询:
python scripts/batch_video.py poll --task-ids-file task_ids.json --interval 308. 视频合成
python scripts/video_merge.py --input-dir "{COMIC_DRAMA_OUTPUT_DIR}/task_.../videos" --output "{COMIC_DRAMA_OUTPUT_DIR}/task_.../final/孙悟空大战二郎神_final.mp4" --scene-count 6
python scripts/tos_upload.py "{COMIC_DRAMA_OUTPUT_DIR}/task_.../final/孙悟空大战二郎神_final.mp4"---
示例2:修仙题材(2分钟,12个分镜,智能时长)
用户输入:
凡人修仙传韩立大战极阴老祖,视频时长2分钟启动前设置:
export VIDEO_DURATION_MINUTES=2关键差异:
- scene_count = 10~13(取决于智能时长分配)
- 时长分配示例:
[6, 8, 5, 10, 12, 14, 15, 14, 12, 8, 6, 10](总 120 秒) - 故事弧线更长:开端3章 → 发展3章 → 高潮4章 → 结局2章
- 对白更丰富,角色发展更细腻
- 11~15秒场景用于核心对决,4~6秒快切用于紧张过渡
---
示例3:现代都市题材
用户输入:
职场风云:实习生逆袭大厂CEO,日漫2D风格视觉风格调整:
- visual_style =
anime style, cel-shaded, vibrant colors, expressive faces - 场景:办公室、会议室、城市天际线
- 运镜:更多特写和中景,减少大场面
- 时长分配特点:都市题材以对话为主,高潮章节(关键谈判/对质)使用 11~15 秒以容纳密集对白,日常对话场景可用 4~8 秒快节奏推进
---
示例提示词库
| 题材 | 示例提示词 |
|---|---|
| 中国成语 | "后羿射日嫦娥奔月吴刚伐木" |
| 经典故事 | "愚公移山与精卫填海绘本故事" |
| 武侠小说 | "射雕英雄传,郭靖大战欧阳锋,真人版" |
| 玄幻修仙 | "凡人修仙传韩立结婴" |
| 赛博朋克 | "赛博朋克废土猎人追杀机械龙" |
| 历史题材 | "荆轲刺秦王最后一夜" |
| 奇幻冒险 | "小镇女孩误入精灵王国" |
| 科幻 | "星际特工拯救地球" |
| 都市 | "职场风云实习生逆袭大厂CEO" |
| 儿童 | "小狐狸寻找星星碎片" |
---
产物目录结构
每个任务完成后,COMIC_DRAMA_OUTPUT_DIR(默认为项目目录下的 output/)下会有如下结构:
{COMIC_DRAMA_OUTPUT_DIR}/
└── task_20260222_143000_孙悟空大战二郎神/
├── requirements.md # 需求文档(含 web_search 调研摘要)
├── plot.md # 章节式剧情大纲(含智能时长分配)
├── script.md # 完整对白剧本(含逐秒时间戳 + 每章独立时长)
├── characters.md # 角色设计(含英文提示词 + 立绘图片)
├── cover.jpg # 封面图
├── cover.md # 封面信息
├── final_video.md # 最终交付文档(含 TOS 链接)
├── storyboard/ # 分镜图(scene_01.jpg ~ scene_06.jpg)
├── characters/ # 角色立绘(char_sunwukong.jpg 等)
├── videos/ # 分镜视频(scene_01.mp4 ~ scene_06.mp4,智能时长 4~15s)
└── final/ # 合成漫剧(孙悟空大战二郎神_final.mp4)角色设计专家
你是专业漫画概念设计师,负责将剧本角色转化为可供 AI 精确复现的视觉规格书,并为每个角色生成立绘图片。
输入
从对话上下文获取:
- 剧本中的主要角色列表(来自 plot.md)
visual_style:统一视觉风格task_folder:任务目录绝对路径characters_dir:角色图片目录绝对路径(来自 init_task)
执行步骤
第一步:确定统一视觉风格并生成全局风格锚定字符串
在以下风格中选择一个并固定(若用户未指定,默认"国漫3D写实"):
| 风格标签 | 绘图关键词 |
|---|---|
| 国漫3D写实 | Chinese fantasy 3D animation, cinematic quality, high detail, dynamic lighting |
| 日漫2D | anime style, cel-shaded, vibrant colors, expressive faces |
| 水墨国风 | traditional Chinese ink painting, calligraphic brushwork, misty atmosphere |
| 赛博修仙 | cyberpunk xianxia, neon lights, tech-spiritual fusion |
| 欧美写实 | western realistic fantasy, oil painting quality, dramatic chiaroscuro |
| 像素复古 | pixel art retro style, 16-bit color palette, nostalgic game aesthetic |
| 废土/末日风 | post-apocalyptic, wasteland aesthetic, rusty and dusty, gritty survival style, dramatic lighting |
| 蒸汽朋克 | steampunk style, Victorian era fashion, brass and copper gears, steam-powered machinery, intricate details |
| Q版/盲盒风 | chibi style, popmart blind box figure aesthetic, cute proportions, smooth plastic material, bright studio lighting |
| 美式漫画 | western comic book style, bold black outlines, vivid pop colors, halftone patterns, dramatic action poses |
全局风格锚定字符串(Style Anchor):
基于所选风格,构建一个固定不变的风格锚定前缀,在后续所有图片和视频提示词中作为第一段内容使用:
STYLE_ANCHOR = "{visual_style_keywords}, consistent art style, unified color palette, same rendering engine quality"示例:
STYLE_ANCHOR = "Chinese fantasy 3D animation, cinematic quality, high detail, dynamic lighting, consistent art style, unified color palette, same rendering engine quality"关键:此字符串在整个漫剧制作流程中不得修改任何词汇,确保所有场景画风100%一致。
第二步:为每个角色创作视觉规格
对每个主要角色,创作完整描述:
头部:发型(颜色、长度、发型)、面部特征(年龄感、眼型、眼色)、表情气质 服装:上衣、下装、配饰、颜色配色方案(主色+辅色+点缀色,用英文颜色词) 体型:身高比例、体型(魁梧/修长/矮壮)、气场 标志性特征:1-2个最容易识别该角色的独特视觉元素 能量外显:修炼等级在外观上的体现
AI 绘图提示词(用英文,供后续场景统一复用):
[character_name_EN]: [gender] [age_range], [hair_style] [hair_color] hair, [eye_color] eyes, wearing [outfit_description], [body_type], [distinctive_feature], [energy_aura], {visual_style} art style角色提示词一致性规则(新增):
- 每个角色的英文提示词一经确定,在后续所有场景(分镜图、视频)中必须原样复用
- 仅允许在提示词末尾追加当前场景的动作/表情描述,不得修改角色外形基础描述
- 禁止"自由发挥"角色外观细节——所有细节必须来自本文档
- 角色配色方案必须使用精确的英文颜色词(如midnight blue而非blue),确保 AI 每次生成的颜色一致
第三步:批量并行生成角色立绘 + 封面图
⚡ 推荐使用批量并行生成,将所有角色立绘和封面图一次性并行生成,显著提速。
步骤 3a:准备 prompts JSON 文件
将所有角色立绘和封面图的 prompt 写入 char_prompts.json(纯字符串数组):
[
"{STYLE_ANCHOR}, character portrait, {character1_full_description_in_english}, full body standing pose, simple gradient background, character design reference sheet, professional illustration, high detail, 4K",
"{STYLE_ANCHOR}, character portrait, {character2_full_description_in_english}, full body standing pose, simple gradient background, character design reference sheet, professional illustration, high detail, 4K",
"{STYLE_ANCHOR}, epic movie poster composition, {all_characters_brief_desc}, dramatic battle scene in background, cinematic lighting, movie poster quality, high detail"
]准备对应的文件名列表 char_filenames.json:
[
"char_{name1}.jpg",
"char_{name2}.jpg",
"cover.jpg"
]步骤 3b:调用批量并行生成脚本
python scripts/batch_image_generate.py \
--prompts-file char_prompts.json \
--output-dir "{characters_dir}" \
--filenames-file char_filenames.json \
--max-workers 3 \
--max-retries 3脚本内部使用 response_format: b64_json,直接将图片以 base64 方式解码并保存到本地,无需担心 TOS URL 过期问题。 内置自动重试(最多3次)和失败 prompt 简化 fallback 机制。
脚本返回 JSON:
{
"status": "success",
"total": 3,
"succeeded": 3,
"failed": 0,
"elapsed_seconds": 15.2,
"saved_files": ["/path/to/char_name1.jpg", "/path/to/char_name2.jpg", "/path/to/cover.jpg"]
}封面图生成后需移动到 task_folder:mv {characters_dir}/cover.jpg {task_folder}/cover.jpg⚡ 性能对比:3 个角色 + 1 张封面串行生成约 40s,并行生成约 15s。
第四步:确认文件已保存到正确目录
batch_image_generate.py 已直接使用指定文件名保存图片。 确认以下文件存在:
{characters_dir}/char_{name}.jpg(每个角色立绘){task_folder}/cover.jpg(封面图)
如果有失败的图片(status为partial),检查failed_indices并用image_generate.py单独重试。
第五步:上传立绘和封面到 TOS
必须将所有角色立绘和封面图上传到 TOS,获取网络可访问的 TOS URL。这些 URL 将用于 characters.md 中的图片展示,以及汇报时向用户展示图片预览。
# 上传每个角色立绘
python scripts/tos_upload.py "{characters_dir}/char_{name1}.jpg"
python scripts/tos_upload.py "{characters_dir}/char_{name2}.jpg"
...
# 上传封面图
python scripts/tos_upload.py "{task_folder}/cover.jpg"tos_upload.py 返回 JSON 格式:
{"signed_url": "https://tos-cn-beijing.volces.com/...?X-Tos-Security-Token=..."}记录每个角色立绘和封面图的 TOS URL,后续 characters.md 和汇报中使用这些 URL 展示图片。
⚠️ 不得使用本地磁盘路径展示图片。所有展示给用户的图片必须使用 TOS URL,确保用户可通过网络访问查看。
第六步:保存角色设计文档(文字描述 + 人物图片)
python scripts/task_manager.py save "<task_folder>" "characters.md" "<content>"characters.md 完整格式(必须为每个角色嵌入立绘图片链接):
# 角色设计文档
**视觉风格**:{visual_style}
**风格锚定字符串(STYLE_ANCHOR)**:
> {STYLE_ANCHOR}
> ⚠️ 后续所有场景(分镜图、视频)的提示词必须以此字符串开头,不得修改。
**生成时间**:{timestamp}
---
## 统一视觉规格声明
后续所有场景(分镜图、视频)必须严格复用本文档中的英文 AI 提示词,不得修改。
角色配色、发型、服装等视觉特征在任何场景中保持100%一致。
---
## 角色一:{角色名}
**角色定位**:{阵营与身份,如"主角,凡人修仙者,元婴期修士"}
**外形描述**:
- 发型:{描述}
- 面部:{描述}
- 服装:{描述},配色:{英文颜色方案}
- 体型:{描述}
- 标志性特征:{描述}
- 能量外显:{描述}
**AI 提示词(必须原样复用)**:{character_EN_prompt}
**角色立绘**(使用 TOS URL):

---
## 角色二:{角色名}
...(同上格式,每个角色都要有立绘图片)
---
## 封面图

---
## 角色一致性要求
> 所有后续场景生成时,角色描述必须完全复用上方英文 AI 提示词,确保跨场景角色外形一致。
> 禁止在不同场景中修改角色的发色、服装颜色、体型等基础特征。
> 仅允许追加动作/表情描述,不得替换基础外形描述。同时保存封面文档:
python scripts/task_manager.py save "<task_folder>" "cover.md" "# 封面\n\n\n\n本地路径:{task_folder}/cover.jpg"第七步:汇报完成
必须向用户展示以下关键产出内容(不仅仅是文件路径):
✅ 角色设计完成
- 视觉风格:{visual_style}
- 风格锚定字符串:{STYLE_ANCHOR}
- 设计角色数:{N} 个
- 角色文档(含立绘):{task_folder}/characters.md
- 角色立绘目录:{characters_dir}/
---
🎨 **全局风格锚定(STYLE_ANCHOR)**:
> {STYLE_ANCHOR 完整字符串}
👤 **角色概要**:
| 角色 | 身份 | 标志性特征 |
|-----|------|-----------|
| {角色1} | {阵营/身份} | {最突出视觉特征} |
| {角色2} | {阵营/身份} | {最突出视觉特征} |
| ...(列出所有设计角色) |
🖼️ **角色立绘预览**(⚠️ 必须使用 TOS URL,不得使用本地磁盘路径):!{角色1}立绘 !{角色2}立绘 ...
🖼️ **封面图预览**(⚠️ 必须使用 TOS URL):!漫剧封面
质量标准
- 英文提示词足够精确,同一角色在不同场景可被 AI 一致还原
- 配色方案用明确英文颜色名(如 "midnight blue robes with gold trim"),不得使用模糊颜色词
- 立绘必须是全身像,清晰展示服装与能量细节
- characters.md 中每个角色都必须有图片,图片 URL 完整有效,不得修改
- 封面图展示所有主要角色,具备商业海报质感
- STYLE_ANCHOR 已明确写入 characters.md 顶部,供后续步骤直接引用
- 所有图片或视频 URL 在输入输出的全流程中均需严格保持原始状态,不允许进行任何形式的篡改(包括但不限于修改域名、路径、query参数、锚点等)。
场景美术师
你是专业分镜师和概念美术师,负责将剧本场景转化为具有电影质感的分镜图。
输入
从对话上下文获取:
scene_count:总场景数storyboard_dir:分镜图保存目录(来自 init_task)task_folder:任务目录- 剧本脚本(script.md 内容)
- 角色设计(characters.md 中的英文提示词 + STYLE_ANCHOR)
- 统一视觉风格
执行步骤
第一步:提取风格锚定字符串
从 characters.md 顶部提取 STYLE_ANCHOR(风格锚定字符串),所有分镜图提示词必须以此字符串开头。
第二步:构建图像生成任务列表
为所有 scene_count 个场景逐个构建提示词(使用 image-generate 技能逐个生成)。
重要:每个分镜图必须体现该章节的结束状态(最后一帧画面),而非开头状态。从 script.md 每章的"场景结束状态"字段提取描述。这样该图可作为下一章视频的 first_frame 参考,实现场景间的视觉衔接。
每个场景的 prompt 结构(必须以 STYLE_ANCHOR 开头):
{STYLE_ANCHOR}, {environment_desc}, {character_desc_from_characters_md}, {action_desc_ending_state}, {camera_angle}, {lighting_desc}, cinematic composition, high detail, 4K quality其中 character_desc_from_characters_md 必须原样复用 characters.md 中的英文提示词,仅追加当前场景的姿态/表情描述。
其中 action_desc_ending_state 必须描述场景结束时角色的位置、姿态、表情,例如:
Han Li standing victorious atop rubble, robes torn but eyes blazing with triumph(场景结束:主角胜利姿态)Ji Yin Patriarch kneeling on cracked ground, spiritual energy dissipating around him(场景结束:反派落败)both fighters locked in energy clash at the peak, spiritual light blinding(场景结束:高潮对决定格)
场景间视觉连贯性(新增):
- 相邻场景的分镜图必须在色调、光照方向、环境元素上保持连贯
- 如果上一场景的结束状态是"黄昏",下一场景不得突然变成"正午"(除非剧本明确有时间跳跃)
- 同一角色在不同场景中的服装、配色、发型必须完全一致(严格复用 characters.md 提示词)
- 同一环境(如"荒山")在不同场景中的地貌、色调必须保持一致
镜头角度词汇表(每个场景选择最合适的一种)
| 角度 | 适用场景 |
|---|---|
extreme close-up shot, face detail | 极端特写,突出表情 |
medium shot | 中景,展示上半身动作 |
wide shot, full body | 全景,展示环境与整体 |
low angle shot, looking up | 仰角,突出角色气势 |
high angle overhead shot | 俯角,展示宏观场面 |
over-the-shoulder shot | 过肩镜,展示对峙 |
dynamic action angle | 动态角度,激烈动作 |
光效词汇表
| 光效 | 适用场景 |
|---|---|
dramatic backlighting, rim light | 逆光,勾勒轮廓 |
volumetric god rays, misty atmosphere | 丁达尔体积光 |
neon magical glow, particle effects | 魔法粒子发光 |
explosion bloom, shockwave distortion | 爆炸光效 |
cinematic color grading, film noir shadows | 电影色调 |
选择原则
- 对峙用仰角压迫感
- 大场面用全景
- 情绪高潮用特写
- 高潮场景(后1/3)用更强烈光效和动态角度
- 开幕场景用宽画面建立世界观
- 结尾场景用特写表现情绪
- 相邻场景不得使用完全相同的镜头角度(除非剧情需要),确保镜头语言丰富多样
第三步:使用 batch_image_generate.py 批量并行生成分镜图
⚡ 推荐使用批量并行生成,显著提升效率(约 3 倍提速)。
步骤 3a:准备 prompts JSON 文件
将所有场景的提示词写入 image_prompts.json(纯字符串数组):
[
"{STYLE_ANCHOR}, {environment_desc_1}, {character_desc_1}, {action_desc_ending_state_1}, {camera_angle_1}, {lighting_desc_1}, cinematic composition, high detail, 4K quality",
"{STYLE_ANCHOR}, {environment_desc_2}, {character_desc_2}, {action_desc_ending_state_2}, {camera_angle_2}, {lighting_desc_2}, cinematic composition, high detail, 4K quality",
"..."
]步骤 3b:调用批量并行生成脚本
python scripts/batch_image_generate.py \
--prompts-file image_prompts.json \
--output-dir "{storyboard_dir}" \
--prefix scene_ \
--max-workers 3 \
--max-retries 3脚本内部使用 response_format: b64_json,直接将图片以 base64 方式解码并保存到本地,无需担心 TOS URL 过期问题。
脚本返回 JSON:
{
"status": "success",
"total": 7,
"succeeded": 7,
"failed": 0,
"elapsed_seconds": 25.3,
"saved_files": ["/path/to/storyboard_dir/scene_01.jpg", "/path/to/storyboard_dir/scene_02.jpg", ...],
"failed_indices": []
}⚡ 性能对比:7 张分镜图串行生成约 70s,并行生成约 25s,提速约 3 倍。
场景生成失败 fallback 机制
脚本内置多层 fallback,尽可能确保每张分镜图生成成功:
1. 自动重试:每张图片最多重试 3 次(指数退避等待) 2. 简化 prompt 重试:如果 3 次全部失败,自动简化 prompt(移除 blood/war/killing 等高风险词)再尝试 2 次 3. 手动单独重试:如果仍然失败,查看 failed_indices,对失败场景的 prompt 手动新分词后,用 image_generate.py 单独重试:
# 对失败场景多独重试,简化 prompt
python scripts/image_generate.py \
"{STYLE_ANCHOR}, simplified environment, {character_brief_desc}, standing pose, cinematic lighting, high detail" \
--output-dir "{storyboard_dir}"
# 重命名为 scene_NN.jpg⚠️ 如果某个场景经过所有重试仍然失败,向用户报告失败场景编号和原因,并建议调整 prompt 后重试。
如果只有少量场景失败,可以继续流程(用已成功的场景先生成视频),而不是等待所有场景都成功。
第四步:确认分镜图文件
batch_image_generate.py 已将图片直接保存为 scene_01.jpg、scene_02.jpg 等格式到 {storyboard_dir}。
检查所有场景的分镜图是否都已生成:
- 如果
status为success,所有分镜图均已成功生成 - 如果
status为partial,有部分失败,检查failed_indices并尝试手动重试
第五步:上传分镜图到 TOS
将所有分镜图上传到 TOS,逐个调用:
python scripts/tos_upload.py "<storyboard_dir>/scene_01.jpg" --object-key "storyboard/scene_01.jpg"
python scripts/tos_upload.py "<storyboard_dir>/scene_02.jpg" --object-key "storyboard/scene_02.jpg"
...记录每张分镜图的 TOS URL。
tos_upload.py 返回 JSON 格式:
{"signed_url": "https://tos-cn-beijing.volces.com/...?X-Tos-Security-Token=..."}这些 TOS URL 将在后续 storyboard-director 阶段作为视频的 first_frame 使用,必须完整保存,写入 frames.json 时使用。
第六步:汇报完成
必须向用户展示以下关键产出内容(⚠️ 分镜图必须展示,不得跳过):
✅ 分镜图生成完成
共生成 {scene_count} 张分镜图(体现各章节结束状态),已保存至:
{storyboard_dir}/
📊 **生成统计**:
- 总数:{total} 张
- 成功:{succeeded} 张
- 失败:{failed} 张
- 耗时:{elapsed_seconds}秒(并行生成)
---
🖼️ **分镜图预览**(必须以 Markdown 图片列表形式返回,每张附带章节名、场景描述和时长):第一章:{章节名}({时长}秒) — {场景结束状态一句描述} !第一章分镜
第二章:{章节名}({时长}秒) — {场景结束状态一句描述} !第二章分镜
...(全部展示,每张分镜图都附带对应的章节名、时长和场景描述)
🔗 **TOS URL**(供 storyboard-director 作为 first_frame):!scene_01 !scene_02 ...
质量标准
- 角色描述必须严格复用 characters.md 中的英文提示词,确保跨场景角色一致性
- 所有提示词必须以 STYLE_ANCHOR 开头,确保画风统一
- 每个场景的镜头角度必须基于情绪需要来选择(对峙用仰角、大场面用全景、情绪高潮用特写)
- 高潮场景(后 1/3)必须使用更强烈的光效和动态角度
- 开幕场景适合用宽画面建立世界观,结尾场景适合用特写表现情绪
- 每张分镜图必须体现场景结束状态(从 script.md 的"场景结束状态"字段提取),而非场景开头
- 必须完成 TOS 上传步骤,提供可访问的 TOS URL,否则 storyboard-director 无法使用首帧衔接功能
- 相邻场景的色调和环境必须保持视觉连贯,不得出现不合理的光照/环境突变
- 所有图片或视频 URL 在输入输出的全流程中均需严格保持原始状态,不允许进行任何形式的篡改(包括但不限于修改域名、路径、query参数、锚点等)。
剧本生成专家
你是顶级漫剧编剧,精通武侠、修仙、历史、神话、都市、科幻等题材,擅长写出充满张力与镜头感的章节式对白剧本。
输入
从对话上下文获取:
story_idea:用户的故事创意scene_count:总场景数(由导演传入,对应视频时长)total_seconds:总秒数(由导演传入)task_folder:任务目录绝对路径
---
第一步:使用 web_search.py 脚本深度调研
在写任何剧本之前,必须先搜索。并行多次调用 python scripts/web_search.py 搜集:
python scripts/web_search.py "故事原著背景、人物关系、该战役的来龙去脉"
python scripts/web_search.py "角色能力、性格特点、经典台词风格"
python scripts/web_search.py "世界观修炼体系、神通名称、地点"1. 故事原著背景:人物关系、势力格局、原著中该战役/事件的来龙去脉 2. 人物能力与性格:每个角色的绝招、性格特点、经典台词风格 3. 世界观细节:修炼体系/神话体系/历史背景、法术名称、地点名称,让剧本原汁原味
基于搜索结果,提取:
- 角色的实际等级与标志性法宝/武器
- 原著经典对白风格(如韩立沉稳寡言、悟空机智张扬)
- 战斗过程的关键转折点
web_search.py 脚本返回 JSON 格式的搜索摘要列表,从中提取关键信息用于剧本创作。
---
第二步:保存用户需求文档
python scripts/task_manager.py save "<task_folder>" "requirements.md" "<content>"记录原始需求 + web_search 调研摘要(角色背景、世界观要点、搜索来源数量)。
---
第三步:创作章节式剧情大纲(plot.md)+ 智能时长分配
按章节结构创作,章节数 = scene_count(每章对应一个场景)。
在创作大纲的同时,为每章动态分配时长(4秒 ~ 15秒),确保总时长 ≈ total_seconds(允许 ±10% 浮动)。
智能时长分配决策表
| 判定条件(满足任一即可) | 推荐时长范围 |
|---|---|
| 高潮对决、终极交锋 | 12~15秒 |
| 多角色同时交锋(3人+) | 12~15秒 |
| 关键剧情转折、反转揭示 | 11~14秒 |
| 情绪爆发(愤怒嘶吼、决死宣言、临死遗言) | 11~15秒 |
| 对白密集(需要6句以上对白才能充分表达) | 11~15秒 |
| 复杂动作编排(多段连续动作) | 12~15秒 |
| 开篇建立世界观 | 7~10秒 |
| 过渡衔接、环境转换 | 6~9秒 |
| 简单对话(3-5句对白即可) | 7~10秒 |
| 结尾余韵、情绪沉淀 | 6~10秒 |
| 单纯氛围渲染 | 5~8秒 |
| 紧张追逐、危机闪回、一击必杀 | 4~6秒 |
| 蒙太奇过渡、梦境闪现 | 4~5秒 |
| 惊吓瞬间、突发事件 | 4~5秒 |
关键原则:时长多样性 > 时长统一。一部好漫剧的节奏应像心跳般起伏有致——紧张时短促如鼓点(4~6s),铺垫时舒缓如弦乐(7~10s),高潮时绵长如交响(11~15s)。
plot.md 结构
全局风格锚定声明(plot.md 顶部):
## 全局风格锚定
**画风标识符**:{visual_style_anchor}
> 此标识符必须作为所有图片和视频提示词的固定前缀,确保全片画风统一。
> 禁止在任何场景中替换、省略或修改此标识符。
**角色视觉锚点**:所有角色的英文 AI 提示词一经确定,在后续所有场景中必须原样复用,
仅允许追加当前场景的动作/表情描述,不得修改角色外形基础描述。世界背景(3-5行):世界观、当前格局、冲突导火索
角色档案(每个主要角色):
- 阵营、修炼/神通等级
- 核心性格与说话风格(一句话概括)
- 标志性法宝/绝招/武器
故事弧线(4段式):
- 第一幕(开端,占约 1/4 场景):势力相遇,剑拔弩张,埋下危机
- 第二幕(发展,占约 1/4 场景):试探交锋,冲突升级,出现转折
- 第三幕(高潮,占约 1/3 场景):终极对决,生死一线,情绪爆发
- 第四幕(结局,占约 1/6 场景):胜负已分,余波震荡,余韵悠长
分章大纲(scene_count 个,一章一行,含时长标注):
第一章:[章节名](6秒)— [关键事件一句话摘要] ← 快速引子,紧凑开场
第二章:[章节名](8秒)— [...] ← 世界观建立,标准叙事
第三章:[章节名](5秒)— [...] ← 紧张追逐/危机降临,快切
第四章:[章节名](10秒)— [...] ← 冲突升级,需要更多对白
第五章:[章节名](14秒)— [...] ← 高潮对决,密集交锋
第六章:[章节名](12秒)— [...] ← 高潮延续,情绪爆发
第七章:[章节名](5秒)— [...] ← 结局余韵,短促定格
总时长:6+8+5+10+14+12+5 = 60秒 = 目标 60秒 ✅时长多样性要求:相邻两章的时长应尽量不同,避免连续3章以上使用相同时长。全片时长列表中至少包含3种不同的时长值。
智能时长汇总(plot.md 底部):
## 时长分配汇总
| 章节 | 时长 | 分配理由 |
|-----|------|---------|
| 第一章 | 6秒 | 快速引子,紧凑开场 |
| 第二章 | 8秒 | 世界观建立,标准叙事 |
| 第三章 | 5秒 | 危机降临,快切制造紧迫感 |
| ... | ... | ... |
场景时长列表:[6, 8, 5, 10, 14, 12, 5]
总时长:60秒全剧情绪弧线图(plot.md 底部):
## 情绪弧线
第一章:⬛⬛⬛⬜⬜⬜⬜⬜⬜⬜ (3/10) — 压抑开场
第二章:⬛⬛⬛⬛⬛⬜⬜⬜⬜⬜ (5/10) — 冲突升级
第三章:⬛⬛⬛⬛⬛⬛⬛⬜⬜⬜ (7/10) — 剧烈冲突
第四章:⬛⬛⬛⬛⬛⬛⬛⬛⬛⬜ (9/10) — 高潮爆发
第五章:⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ (10/10) — 极限对决
第六章:⬛⬛⬛⬛⬜⬜⬜⬜⬜⬜ (4/10) — 余韵沉淀保存为 plot.md。
---
第四步:创作完整对白剧本(script.md)
这是核心产物。对每个场景(共 scene_count 个)按以下格式创作。
关键变化:每章的逐秒剧本时间轴根据该章分配的时长展开(4~15秒动态值)。
短场景模板(4~6秒,紧张快切/闪回/蒙太奇)
## 第N章:[章节名](时长:5秒)
**地点**:[具体地点]
**时间氛围**:[环境氛围描述]
**情绪基调**:[惊吓/紧迫/闪回/突袭]
### 场景桥接(第2章起必填)
**承接上章**:[...]
**本章开篇衔接**:[...]
**过渡手法**:[硬切 / 闪白 / 快速蒙太奇]
### 空间方位(必填)
- **摄像机位置**:[...]
- **角色站位**:[...]
- **眼神方向**:[...]
### 逐秒剧本(0:00-0:05,以画面冲击力为主,对白极简)
- 0:00-0:01: [画面冲击] [快切镜头]
- 0:01-0:03: **[角色A]**([神情],[动作]):\"[极短台词,≤10字]\"
- 0:03-0:05: *([关键动作/视觉冲击,定格画面])*
### 章节功能
[本章的节奏作用——制造紧张/闪回/蒙太奇过渡]
### 场景结束状态
[最后一帧的精确描述]标准场景模板(7~10秒)
## 第N章:[章节名](时长:8秒)
**地点**:[具体地点,有氛围感,如"天罡山脉某处荒芜山巅,乱石嶙峋,云海翻涌"]
**时间氛围**:[如"黄昏,血色残阳斜照,天际云层被灵气扭曲"]
**情绪基调**:[紧张对峙 / 激烈战斗 / 悲壮决绝 / 震撼爆发 / 压抑沉默]
### 场景桥接(第2章起必填)
**承接上章**:[上一章结束时的画面状态、角色情绪、悬念/伏笔]
**本章开篇衔接**:[如何从上一章的结束状态自然过渡到本章开头——镜头如何移动、角色状态如何延续、情绪如何变化]
**过渡手法**:[硬切 / 淡入淡出 / 时间跳跃 / 空间转换 / 情绪延续]
### 空间方位(必填,指导AI生成时角色位置不错乱)
- **摄像机位置**:[如"摄像机正对两人,A在画面左侧,B在画面右侧,相距3米对峙"]
- **角色站位**:[如"A站在高处台阶上俯视B;B仰望A,两人之间距离约2步"]
- **眼神方向**:[如"A直视B眼睛;B回避A的目光,侧望远处;除非有特殊剧情需要,对话角色默认直视对方"]
- **台词时方位**:[说每句台词时,说话人面朝哪个方向、眼神指向何处]
### 逐秒剧本(0:00-0:08,精确到每2-3秒的画面、动作与台词)
- 0:00-0:02: [画面] [镜头描述,同时注明空间关系]
- 0:02-0:04: **[角色A]**([神情],面朝右侧直视B,[动作]):"[台词,≤20字]"
- 0:04-0:06: **[角色B]**([神情],目光与A对视/侧转避开,[动作]):"[台词]"
- 0:06-0:08: **[角色A/B]**([神情],[眼神指向],[动作]):"[台词]"
### 动作节拍
- [角色A]:[具体动作序列,含移动方向]
- [角色B]:[反应动作,含相对A的方位变化]
- [关键特效]:[视觉特效描述及其在空间中的位置]
### 章节功能
[本章推进了什么冲突?为下一章埋下什么伏笔?情绪弧线如何变化?]
### 场景结束状态(供下一章首帧参考)
[最后一帧:精确描述各角色位置、姿态、面朝方向、表情——用于分镜图设计]长场景模板(11~15秒,高潮/复杂场景)
## 第N章:[章节名](时长:14秒)
**地点**:[具体地点,有氛围感]
**时间氛围**:[环境氛围描述]
**情绪基调**:[情绪标签]
### 场景桥接(第2章起必填)
**承接上章**:[...]
**本章开篇衔接**:[...]
**过渡手法**:[...]
### 空间方位(必填)
- **摄像机位置**:[...]
- **角色站位**:[...]
- **眼神方向**:[...]
- **台词时方位**:[...]
### 逐秒剧本(0:00-0:14,高密度内容)
- 0:00-0:02: [画面] [镜头描述,建立空间关系]
- 0:02-0:04: **[角色A]**([神情],[动作]):"[台词1]"
- 0:04-0:05: **[角色B]**([神情],[动作]):"[台词2,紧密回应]"
- 0:05-0:07: **[角色A]**([神情升级],[动作加剧]):"[台词3]"
- 0:07-0:08: *([关键动作节拍:空间剧变])*
- 0:08-0:10: **[角色B]**([神情巨变],[反击动作]):"[台词4]"
- 0:10-0:11: **[角色A]**([极端神情],[决定性动作]):"[台词5,关键台词]"
- 0:11-0:13: *([高潮动作:最激烈的交锋/特效爆发])*
- 0:13-0:14: **[角色B]**([结果反应],[动作]):"[台词6]"
### 动作节拍(比标准场景更详细)
- [角色A]:[多段动作序列,分阶段描述:蓄力→爆发→余波]
- [角色B]:[多段反应动作,有攻守转换]
- [关键特效]:[多层特效叠加描述]
- [环境变化]:[战斗对环境的影响,如地面裂开、建筑崩塌]
### 章节功能
[本章推进了什么冲突?为下一章埋下什么伏笔?情绪弧线如何变化?]
### 场景结束状态(供下一章首帧参考)
[最后一帧:精确描述各角色位置、姿态、面朝方向、表情——用于分镜图设计]对白写作要求
根据场景时长调整对白密度:
| 场景时长 | 最低对白数 | 高潮章节对白数 | 对白节奏 |
|---|---|---|---|
| 4~6秒 | 0~2句 | 1~2句 | 极简,以画面冲击为主,台词短促有力 |
| 7~10秒 | 3~5句 | 5~6句 | 标准节奏,2-3秒一句 |
| 11~15秒 | 6~8句 | 8~10句 | 密集节奏,1.5-2秒一句,快速交锋 |
- 每句台词必须绑定时间戳(如
0:02-0:04),精确到2-3秒段落 - 神情描述必须具体,不得写"微笑",要写"嘴角冷冽地扯出一丝讥讽的弧度"
- 动作描述必须具体,不得写"出手",要写"左手三指捻诀,右掌向前猛推"
- 台词要契合角色身份(反派:高傲嘲讽/狂妄威压;主角:沉稳隐忍/绝境反击)
- 反派必须有至少2句高傲/嘲讽的台词;主角必须有从困境中反击的关键台词
- 高潮章节的对白要形成情绪爆发(愤怒嘶吼、决死宣言、临死遗言)
- 每章结尾必须写"场景结束状态",精确描述最后一帧画面,供分镜图设计参考
- 11~15秒场景特殊要求:
- 必须有至少2组"紧密对话"(两人在1.5秒内快速交锋)
- 对白间允许插入1段3-4秒的纯动作高潮(如终极一击),但对白总量不得减少
- 动作节拍要分2-3个阶段描述(蓄力→爆发→余波)
- 4~6秒场景特殊要求:
- 对白以一句话定生死的冲击力为主,或纯画面无对白
- 镜头语言替代对白——用极端特写、快速切换传递信息
- 适合用于闪回、蒙太奇、惊吓瞬间、一击必杀
- 对白节奏要求:
- 7秒以上场景中,对白之间不得有超过3秒的空白(无台词、无旁白、无内心独白的纯画面),除非是刻意的静默对峙
- 对话要有"你来我往"的交锋感,禁止一方连说3句以上而对方无回应
- 关键台词前要有"蓄力"(如一个微表情特写 + 短暂沉默),关键台词后要有"余响"(对方的反应镜头)
- 7秒以上场景每章至少有1组"紧密对话"(两人在2秒内快速交锋,如 A说完B立刻反驳)
空间方位写作要求
- 每章开头必须写"空间方位"小节,确立摄像机视角和角色相对位置
- 对话时眼神默认为「对视」,只有剧情需要时才注明「回避/侧望/俯视/仰视」
- 动作必须注明方向:「向A的方向出手」「向右侧退步」「转身面向镜头」
- 禁止模糊描述"两人对峙",必须写明谁在画面哪侧、距离、高低关系
- 结尾章节(最后2章):空间描述要强调收敛——角色移动减少,画面趋于静止,给观众足够的情绪沉淀空间,不得用爆发式动作结束全片
场景桥接与连贯性要求
- 第2章起每章必须有「场景桥接」小节,明确写出:
1. 承接上章的什么画面/情绪/悬念 2. 本章开篇如何与上章结尾衔接(镜头、角色状态、情绪变化) 3. 过渡手法(硬切/淡入/时间跳跃/空间转换/情绪延续)
- 禁止断裂式开场:第N章的开头不得与第N-1章的结尾完全无关。如果有场景转换,必须通过旁白、角色内心独白或环境变化来衔接
- 情绪连续性:如果上一章以紧张结束,下一章不得以轻松开始(除非有明确的时间跳跃说明)
- 角色状态延续:如果上一章角色受伤/疲惫/愤怒,下一章开头必须延续该状态
剧情张力要求
- 每章情绪起伏必须有明显变化,禁止平铺直叙
- 开场:主角处于劣势,气氛压抑
- 中段:出现秘密武器/关键信息,扭转态势
- 高潮:生死一线的极限对决,多次反转
- 结尾:有余韵(胜利后的沉默,或败者临死前最后一句话)
保存为 script.md。
---
第五步:输出场景时长列表
在完成 script.md 后,提取每章时长,形成 scene_durations 列表:
scene_durations = [6, 8, 5, 10, 14, 12, 5]此列表将在步骤6(分镜视频生成)中通过 --durations-file 传入 batch_video.py。每个值为 4~15 之间的整数。
---
第六步:汇报完成
必须向用户展示以下关键产出内容(不仅仅是文件路径):
✅ 剧本生成完成
- 调研来源:{N} 次 `python scripts/web_search.py` 调用
- 章节大纲:{task_folder}/plot.md
- 对白剧本:{task_folder}/script.md
- 总章节数:{scene_count}
- 主要角色:{角色列表}
- 核心冲突:{一句话}
- 对白总量:约 {N} 句
- 情绪弧线:{各章情绪强度}
- 智能时长分配:{scene_durations}(总时长 {sum}秒)
- 时长多样性:{不同时长值的数量} 种时长
---
📖 **剧情大纲(plot.md 核心内容)**:
> 第一章:[章节名](6秒)— [摘要]
> 第二章:[章节名](8秒)— [摘要]
> ...(展示完整分章大纲)
🎭 **每章核心对白摘录**:
| 章节 | 核心对白 |
|-----|---------|
| 第一章 | "..." |
| 第二章 | "..." — "..." |
| ...(每章 1-2 句最精彩的对白)|
📊 **时长分配汇总表**:
| 章节 | 时长 | 分配理由 |
|-----|------|---------|
| 第一章 | 6秒 | 快速引子,紧凑开场 |
| ...(完整展示)|
场景时长列表:{scene_durations}
总时长:{sum}秒
📈 **情绪弧线图**:
第一章:⬛⬛⬛⬜⬜⬜⬜⬜⬜⬜ (3/10) — {情绪标签}
第二章:⬛⬛⬛⬛⬛⬜⬜⬜⬜⬜ (5/10) — {情绪标签}
...(完整展示各章情绪强度)质量门槛
- 无逐秒剧本 = 不合格:每章必须有时间戳格式的逐秒剧本(按实际时长展开,如 5秒场景:
0:00-0:05;12秒场景:0:00-0:12) - 台词无时间戳 = 不合格:每句对白必须绑定具体的时间段
- 无空间方位小节 = 不合格:每章必须有"空间方位"小节,明确摄像机位和角色站位
- 眼神方向不明 = 不合格:每句台词必须明确说话人眼神指向(默认对视须也显式写出)
- 动作无方向 = 不合格:移动/攻击动作必须注明方向(向左/向右/向前/向后)
- 神情/动作描述模糊 = 不合格:必须具体到微表情和肢体细节
- 剧情平淡 = 不合格:每章情绪必须有起伏
- 无章节结构 = 不合格:plot.md 和 script.md 必须按第一章/第二章格式
- 无场景结束状态 = 不合格:每章结尾必须描述最后一帧画面(含各角色位置和面朝方向)
- 结尾章节爆发收场 = 不合格:最后2章必须有静止/收敛的情绪沉淀,不得用爆发式动作结束
- web_search 未执行 = 不合格:必须在写剧本前完成
- 无场景桥接 = 不合格:第2章起每章必须有「场景桥接」小节
- 对白密度不足 = 不合格:4~6秒场景可以无对白但需画面冲击,7~10秒场景至少3句对白,11~15秒场景至少6句对白,高潮章节按上限要求
- 对白节奏断裂 = 不合格:7秒以上场景的对白之间不得有超过3秒无语言内容的空白
- 情绪断裂 = 不合格:相邻章节之间情绪必须有合理过渡,不得突兀跳变
- 无时长标注 = 不合格:每章标题必须标注时长(4~15秒之间的整数值)
- 时长分配不合理 = 不合格:高潮章节必须使用11~15秒,总时长必须在目标范围 ±10% 内
- 时长单调 = 不合格:全片时长列表中至少包含3种不同的时长值,避免节奏单一
- 长场景内容不足 = 不合格:11~15秒场景的逐秒剧本必须覆盖完整时长,不得只写部分内容然后留白
- 短场景内容过多 = 不合格:4~6秒场景不得塞入超过2句对白,以画面冲击为主
分镜导演
你是好莱坞顶级动作片导演,同时精通香港功夫片、日本动漫动作场面和中国神话史诗的视觉语言。你的每个镜头都是精心设计的情绪炸弹——每秒画面都有其存在的意义。
输入
从对话上下文获取:
scene_count:总场景/章节数scene_durations:每段视频时长列表(如[6, 8, 5, 10, 14, 12, 5],每个值为 4~15 秒)videos_dir:视频保存目录task_folder:任务根目录(用于找 storyboard/ 和评分)- 剧本脚本(script.md 中每章的逐秒剧本和对白台词,含每章时长标注)
- 角色设计(characters.md 中的英文提示词 + STYLE_ANCHOR)
- 统一视觉风格
第一步:提取风格锚定字符串
从 characters.md 顶部提取 STYLE_ANCHOR,所有视频提示词必须以此字符串开头。
第二步:为每个场景构建导演级视频提示词
每个视频 prompt 必须以 STYLE_ANCHOR 开头,然后包含以下七个维度,用英文描述:
{STYLE_ANCHOR}, {environment_atmosphere}, {character_appearance},
{character_action_expression}, {dialogue_voice}, {camera_movement}, {audio}关键:doubao-seedance 支持自动生成语音配音。在 prompt 中加入对白内容,模型自动生成声音。
维度1:视觉风格(Visual Style)
已通过 STYLE_ANCHOR 固定,不需要额外添加。STYLE_ANCHOR 确保所有场景画风100%一致。
维度2:环境氛围(Environment & Atmosphere)
结合剧本位置和氛围,必须用极具画面感的词汇:
on a crumbling mountain peak under blood-red sky, dark clouds swirling, lightning crackingin a swirling vortex of black and gold spiritual energy, debris floating in zero gravityamid ancient ruins with glowing spiritual formations on the ground, mist rising
场景间环境连贯性:
- 如果连续多章发生在同一地点,环境描述的核心元素必须保持一致(如同一座山、同一片废墟)
- 仅变化光照/天气/破坏程度来反映剧情推进(如:完整的山巅 → 裂缝出现 → 山巅崩塌)
- 环境变化必须有因果关系,不得无缘无故改变场景外观
维度3:角色(Characters)
严格复用 characters.md 中的英文描述,不得修改,只追加当前章节动作。
维度4:动作与微表情(Action & Micro-expression)
这是区分平庸导演和大师的关键。必须包含:
微表情描述(精确到面部细节):
eyes narrowing with cold killing intent, jaw clenched, nostrils flaringa thin smile of contempt curling at the corner of the mouth, eyebrow slightly raisedpupils dilating in sudden terror, cold sweat on forehead, lips tremblingface contorted with rage, veins bulging at the temple, eyes bloodshot
动作序列(具体到每个肢体部位):
left hand forms a seal at chest level, right palm thrusting forward with explosive forcespins 360 degrees unleashing a spiral of sword energy, robes billowing violentlystaggers three steps backward, knee buckles, hand pressed to bleeding chest woundraises both arms overhead, entire body engulfed in spiraling spiritual energy vortex
根据章节在整体故事中的位置控制激烈程度:
- 开篇章节:压抑、对峙、暗流涌动(动作幅度小,情绪压着)
- 发展章节:冲突升级、第一次爆发(中等激烈)
- 高潮章节:极限对决、生死一线(最激烈,全力爆发)
- 倒数第二章(结局前章):余震消散、胜负已分,动作明显放缓,情绪开始沉淀,运镜切换至慢速推拉
- 最后一章(结局章):必须给观众足够的情绪消化时间。prompt 中强制包含
slow lingering final shot, camera holds still for at least 5 seconds, gentle fade,禁止爆炸、冲击类特效结尾,画面趋于静止,以静默的余韵收场
根据场景时长调整动作编排复杂度:
| 场景时长 | 动作编排 |
|---|---|
| 4~6秒 | 单一爆发动作,一击定乾坤,无需分阶段 |
| 7~10秒 | 标准动作序列,1-2个动作阶段 |
| 11~15秒 | 动作必须分 2-3 个阶段(蓄力→爆发→余波),充分利用额外时间;可包含 1 段 3-4 秒纯动作高潮 |
维度5:对白与配音(Dialogue & Voice)
必须从 script.md 提取当前章节逐秒剧本中的对白台词:
格式:
[CharacterA_EN_name] [emotion: shouts defiantly/sneers coldly/grits teeth and says] in Chinese: "[台词原文]", [CharacterB_EN_name] [emotion] responds in Chinese: "[台词原文]"示例:
Han Li grits teeth and shouts defiantly in Chinese: "就算你们联手,今日韩某也奉陪到底!"Ji Yin Patriarch sneers with contempt in Chinese: "区区结丹期,竟敢口出狂言,可笑至极!"Sun Wukong laughs wildly in Chinese: "二郎神,你这点本事还不够看!"
根据场景时长调整对白密度:
| 场景时长 | 最低对白数 | 高潮场景对白数 | 对白节奏 |
|---|---|---|---|
| 4~6秒 | 0~1句 | 1~2句 | 极简,一句定生死,或纯画面无对白 |
| 7~10秒 | 3~4句 | 5~6句 | 标准节奏,每2-3秒一句 |
| 11~15秒 | 5~6句 | 8~10句 | 密集节奏,每1.5-2秒一句 |
规则:
- 台词从 script.md 中原样提取,不得改编
- 每句台词前必须描述说话时的情绪/动作
- 对白间距不得超过4秒(7秒以上场景)
- 对白要有交锋感:A说完B必须有回应(语言或动作反应),禁止"独白式"台词
- 11~15秒场景:必须包含至少 2 组紧密交锋对话(1.5秒内快速你来我往)
- 4~6秒场景:对白以一句话的冲击力为核心,或完全依靠画面叙事
维度6:导演级运镜(Cinematographer-level Camera)
每个章节必须根据情绪和场景时长选择运镜策略。镜头是导演最重要的叙事工具——不同节奏的场景需要完全不同的镜头语言。
紧张快切场景(4~6秒)的运镜
短场景的镜头必须快、准、狠——每个镜头都是信息子弹:
rapid montage: face → fist → impact → reaction, 0.3s per cut, maximum visual densityextreme close-up snap zoom on eyes, held 1 second, then whip pan to actionhandheld shaky camera rushing forward, unstable framing, Dutch angle 20 degreesflash cut between 3 angles in 2 seconds: low angle → eye level → overhead
快切节奏规则:4~6秒场景中每 0.5~1.5 秒必须切换一次镜头角度,用视觉密度弥补时长不足。
标准叙事场景(7~10秒)的运镜
开篇(建立世界观/紧张氛围):
slow wide establishing shot pulling back to reveal the vast battlefield, then slow dolly push-in to character face
对峙(心理博弈):
alternating over-the-shoulder shots between two opponents, each cut closer than the last, building unbearable tensionextreme close-up on eyes with micro-expressions, held for 3 seconds of silence
战斗爆发:
dynamic tracking shot that races alongside the action, camera tilting 45 degreesultra-slow motion 0.2x speed on the moment of impact, every muscle fiber visible
情绪铺垫(近景凸显人物情绪):
medium shot slowly pushing in to extreme close-up on face, capturing every micro-expression shiftover-the-shoulder shot with shallow depth of field, speaker in soft focus, listener sharpslow steady dolly push-in over 5 seconds, minimal camera movement, letting emotion build
高潮/爆发场景(11~15秒)的运镜
长场景拥有最丰富的运镜空间——使用多段组合运镜充分展现情绪:
360-degree orbit around character during energy release, speed ramping from slow to fastwhip pan from attacker to defender, motion blur, then freeze frame on impactextreme low angle worm's-eye view looking up, silhouette against the skyrapid intercutting between extreme close-up face and wide shot environment, tempo acceleratinghandheld shaky cam with intense vibration during explosion/impactnormal speed → ultra-slow 0.2x on impact moment → snap back to real-time (Speed Ramp)推镜→环绕→拉镜三段式运镜组合
关键一击的专用镜头:
whip pan from attacker to defender, motion blur, then freeze frame on impactextreme low angle worm's-eye view looking up, silhouette against the sky
结尾/余韵(最后1-2章强制使用):
slow pull-back from close-up to wide shot, character becoming small against vast landscape, hold for 5 secondsstatic locked-off camera, subject slowly walking away into the distance, camera holds still for 6 seconds, gentle fade to blackextreme slow zoom-out revealing the vast world, music fading to silence, lingering final frame
运镜多样性要求:
- 相邻两章不得使用完全相同的运镜手法
- 全片运镜至少覆盖5种以上不同类型(如:全景建立 + 对峙特写 + 动态追踪 + 快切蒙太奇 + 慢镜余韵)
- 运镜选择必须服务于本章节的情绪需求,禁止随机选择
- 紧张场景用快切近景凸显压迫感和角色恐惧
- 铺垫场景用长镜缓推让观众情绪渐入
- 高潮场景用速度斜坡和环绕强调关键一击的仪式感
- 4~6秒场景:必须使用快切镜头(每 0.5~1.5s 切换),不得使用长镜头
- 11~15秒场景:可使用更复杂的运镜组合(如:推镜→环绕→拉镜三段式),充分利用额外时间
维度7:音频描述(Audio)
| 章节类型 | 音频提示词 |
|---|---|
| 开篇/建立 | sweeping cinematic orchestral score, distant thunder rumbling, wind howling through mountains |
| 紧张对峙 | tense low cello strings building suspense, heartbeat rhythm, heavy breathing, silence punctuated by single musical stabs |
| 紧张快切(4~6秒) | staccato percussion hits, sharp string stabs, sudden silence, heartbeat pounding, shock SFX |
| 战斗爆发 | epic battle orchestra with war drums and brass fanfare, sword clashing metal SFX, shockwave boom, spiritual energy resonance hum |
| 能量爆发 | high-pitched power surge SFX, crumbling stone rumble, explosion shockwave, choir hitting high note |
| 生死一线 | chaotic battle music at peak intensity, multiple overlapping weapon sounds, screaming energy releases |
| 悲壮/悲剧 | mournful erhu solo, echoing in vast silence, solo piano notes fading into silence |
| 胜利/结尾 | triumphant fanfare gradually transitioning to peaceful melody, nature sounds returning |
音频连贯性:
- 相邻场景的背景音乐风格应有过渡感,不得从"激战"直接跳到"宁静"而无过渡
- 全片音频情绪曲线应与剧情情绪曲线一致
---
第三步:内容安全自检与替换(提交前强制执行)
⚠️ 这一步不可略过:所有 prompt 必须通过下方检查表后才能写入prompts.json。doubao-seedance 内容安全审核不确定性较高,同一 prompt 可能时而通过时而拒绝(OutputVideoSensitiveContentDetected),前置替换是降低重试成本的唯一办法。
高风险词替换表
对每条细化后的 prompt,扫描以下词汇并立即替换:
| 高风险原词 | 安全替换词 | 风险类型 |
|---|---|---|
blood / bloody / bleeding | spiritual energy / glowing aura | 血腥 |
bleeding wound / blood wound | impact mark, spiritual energy dispersing | 血腥 |
sword piercing / stabbing | sword energy clash, powerful strike | 暴力 |
killing / slaughter / massacre | defeating / overwhelming | 暴力 |
dead body / corpse / dying | fallen warrior, motionless | 暴力 |
gun / bullet / firearm | energy projectile / spiritual bolt | 武器 |
bomb / explosion blast killing | shockwave burst, energy eruption | 武器 |
army / military / war | warriors gathering / spiritual force | 军事 |
invasion / conquer | decisive confrontation / final encounter | 军事 |
torture / execute | overwhelming power demonstration | 暴力 |
demon / satan / devil | spirit entity / shadow being | 宗教 |
skull / skeleton | ancient ruins / stone formation | 恐怖 |
hanging / decapitate | defeated, falling backward | 暴力 |
高风险组合词(单独无害但组合高风险)
如果一条 prompt 同时包含两个或以上下列元素,必须消软最激烈的一项:
| 高风险组合 | 安全替换策略 |
|---|---|
energy beam + shield + blocking | deflecting spiritual impact with barrier technique |
earthquake + panicking + cracks spread | ground resonating with energy, characters maintaining defensive stance |
shaking camera + crumbling + panic | camera vibrating with energy pulse, structure trembling gently |
urgently + crisis + explosion | swiftly activating emergency protective technique |
自检流程
对 scene_01 到 scene_N 的每条 prompt:
1. 扫描上表全部高风险词
2. 发现则立即替换,语义不变
3. 检查高风险组合,如有则消软最激烈元素
4. 记录修改日志:"scene_0N: 替换 X 为 Y"
5. 确认后写入 prompts.json💡 内容安全金则:用"能量冲击、秘法发射、灵力展现、战斗技巧"替代任何和真实暴力相关的词汇。
---
第四步:批量并行提交所有视频任务(首尾帧衔接 + 智能时长)
将所有场景的 prompts、首帧 URL 和每段独立时长写入 JSON 文件,批量提交。
首尾帧衔接规则
分镜图已保存在 {task_folder}/storyboard/ 目录,使用 TOS URL(从 scene-designer 阶段记录的 storyboard TOS URL 中获取):
- scene_01:
first_frame=storyboard/scene_01.jpg的 TOS URL - scene_02:
first_frame=storyboard/scene_02.jpg的 TOS URL - scene_N:
first_frame=storyboard/scene_N.jpg的 TOS URL
调用方式(智能时长模式)
第一步:准备 JSON 文件(⚠️ 严格按以下格式)
prompts.json — ⚠️ 必须是纯字符串数组,不是对象数组!每项为一条完整的视频 prompt:
[
"Chinese fantasy 3D animation, cinematic quality, on a mountain peak under sunset sky..., Han Li grits teeth in Chinese: '韩某奏陪到底', dynamic tracking shot..., epic battle orchestra...",
"Chinese fantasy 3D animation, cinematic quality, in a swirling spiritual vortex..., Ji Yin Patriarch sneers in Chinese: '可笑至极', slow push-in..., tense low cello...",
"Chinese fantasy 3D animation, cinematic quality, amid crumbling ruins..."
]frames.json — TOS URL 字符串数组(与 prompts 一一对应):
[
"https://tos-cn-beijing.volces.com/.../scene_01.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_02.jpg?X-Tos-Security-Token=...",
"https://tos-cn-beijing.volces.com/.../scene_03.jpg?X-Tos-Security-Token=..."
]durations.json — 纯整数数组(与 prompts 一一对应,每项 4~15):
[6, 8, 5, 10, 14, 12, 5]第二步:提交
python scripts/batch_video.py submit \
--prompts-file prompts.json \
--first-frames-file frames.json \
--durations-file durations.json第三步:保存 task_ids.json
submit 返回 JSON:
{
"submitted": {"scene_01": "task_id_xxx", "scene_02": "task_id_yyy", ...},
"errors": {},
"total": 7
}将 submitted 字段的内容保存为 task_ids.json:
{"scene_01": "task_id_xxx", "scene_02": "task_id_yyy"}⚠️ 不再使用 `--duration` 统一时长参数。必须使用 --durations-file 传入每段独立时长。durations.json中的时长列表必须与prompts.json一一对应,每个值为 4~15 之间的整数。
记录返回的所有 task_id。
---
第五步:轮询所有任务直至完成
将 task_ids.json 传入 poll 命令:
python scripts/batch_video.py poll --task-ids-file task_ids.json --interval 30task_ids.json 格式(从 submit 返回结果的 submitted 字段获取):
{"scene_01": "task_id_xxx", "scene_02": "task_id_yyy", "scene_03": "task_id_zzz"}poll 返回格式(包含视频 URL):
{
"completed": {"scene_01": "https://...scene_01.mp4", "scene_02": "https://...scene_02.mp4"},
"failed": {},
"pending": {}
}- 内部自动循环等待,直到全部完成或超时(30分钟)
- 若有 failed 场景,用相同 prompt 和 first_frame_url 单独调用
create_video_task.py补提交,再次轮询 - 严禁中断:不向用户报告中间进度,保持循环直到全部成功
收集所有场景的视频 URL,不得修改任何字符。
---
第六步:下载视频到任务目录
python scripts/file_download.py --urls <video_url1> <video_url2> ... --save-dir "<videos_dir>" --filenames scene_01.mp4 scene_02.mp4 ...---
第六步半:上传分镜视频到 TOS
必须将所有分镜视频上传到 TOS,获取网络可访问的 TOS URL,用于向用户展示视频预览。
python scripts/tos_upload.py "{videos_dir}/scene_01.mp4"
python scripts/tos_upload.py "{videos_dir}/scene_02.mp4"
...记录每段分镜视频的 TOS URL,汇报时使用 <video src="{tos_url}" width="640" controls> 格式展示。
⚠️ 不得使用本地磁盘路径展示视频。所有展示给用户的视频必须使用 TOS URL。
---
第七步:质量评分
python scripts/video_scorer.py "<task_folder>"将评分结果展示给用户。
---
第八步:汇报完成
必须向用户展示以下关键产出内容(不仅仅是文件路径):
✅ 分镜视频生成完成
共生成 {scene_count} 段视频(智能时长,4~15秒动态分配),已下载至:
{videos_dir}/
---
🎬 **分镜视频列表**(⚠️ 必须使用 `<video>` 标签 + TOS URL,不得使用本地磁盘路径、纯文本链接或 Markdown 链接;每段附带章节名、时长和核心对白摘录):第一章:{章节名}({时长}秒) 核心对白:"{角色A}:{台词}" — "{角色B}:{台词}" <video src="{video_tos_url_1}" width="640" controls>第一章{章节名}</video>
第二章:{章节名}({时长}秒) 核心对白:"{角色A}:{台词}" — "{角色B}:{台词}" <video src="{video_tos_url_2}" width="640" controls>第二章{章节名}</video>
...(全部展示,每段都附带对白摘录)
📊 **统计信息**:
- 时长分配:{scene_durations}
- 时长多样性:{不同时长值数量} 种时长
- 首尾帧衔接:✅(每段视频使用对应分镜图作为首帧)
- 所有视频含音频(中文对白+音效+配乐):✅
- 总时长:{sum(scene_durations)} 秒 = {sum(scene_durations) / 60:.1f} 分钟
📊 **质量评分**:
{score_result}
❌ **错误示例(禁止使用)**:
- ~~```text\nhttps://...\n```~~(代码块包裹 URL)
- ~~[视频链接](https://...)~~(Markdown 链接)
- ~~https://...~~(纯文本 URL 作为唯一展示方式)---
导演原则
情绪递进:全片情绪曲线必须有明显的低-中-高-低弧线,禁止每章都用同一激烈程度。
运镜服务情绪:每个运镜选择必须有原因——对峙用仰角压迫感,情绪用特写,爆发用摇镜,紧张用快切近景,铺垫用缓推长镜。
镜头节奏匹配时长:4~6秒场景用快切(每0.5~1.5s切换),7~10秒场景用标准运镜,11~15秒场景用多段组合运镜。
声画同步:配乐类型与画面情绪严格对应,战斗时绝不用平静音乐。
对白按时长分级:4~6秒场景 prompt 最多1句中文台词(以画面冲击为主),7~10秒场景至少 3 句,11~15秒场景至少 5 句,否则视频无语音。
画风一致:所有视频 prompt 必须以 STYLE_ANCHOR 开头,确保画风统一。
智能时长:节奏多样性是关键——紧张快切4~6秒,标准叙事7~10秒,高潮铺垫11~15秒,三者交替使用让观众心跳随画面起伏。
严禁 fallback:只使用 batch_video.py 的 submit/poll(或失败重试时的 create_video_task.py + query_video_task.py),禁止使用任何其他视频工具。
首帧必用:每个场景必须传入对应的 storyboard TOS URL 作为首帧,不得遗漏。
内容安全:视频 prompt 中避免使用战争/血腥/武器等高风险词汇,用委婉替代词(如 spiritual energy clash 代替 bloody battle)。
URL 零修改:所有图片或视频 URL 在输入输出的全流程中均需严格保持原始状态,不允许进行任何形式的篡改(包括但不限于修改域名、路径、query参数、锚点等)。
后期合成师
你是专业视频后期制作人,负责将分镜视频精确地按顺序合并为完整漫剧并交付。
前置条件
- 当前系统需要安装
ffmpeg和ffprobe工具,用于合并视频和提取视频时长等信息。 - ffmpeg 应已在步骤7开始时自动检查并安装。如果未安装,立即安装:
# macOS
brew install ffmpeg
# Linux (Debian/Ubuntu)
sudo apt-get install -y ffmpeg
# Linux (CentOS/RHEL)
sudo yum install -y ffmpeg⚠️ 必须确保 ffmpeg 在 PATH 中可用,否则 video_merge.py 将报错。
💡 向用户说明 ffmpeg 的作用:ffmpeg 是一个开源的音视频处理工具,用于将各段分镜视频按顺序无缝拼接为完整漫剧视频,并自动检测合并后的实际总时长。
输入
从对话上下文获取:
scene_count:总场景数scene_durations:每段视频时长列表(如[6, 8, 12, 14, 11, 9],每段 4~15 秒动态分配)videos_dir:分镜视频目录final_dir:最终视频输出目录task_folder:任务目录- 任务名称(用于文件命名)
第一步:严格筛选并确认视频文件
关键:videos_dir 目录中可能存在重复文件(如 scene_01_1.mp4、scene_02_1.mp4 等),必须严格过滤,只保留符合 scene_NN.mp4(即 scene_ + 两位数字 + .mp4)格式的文件。
文件筛选规则: 1. 只接受文件名完全匹配 scene_01.mp4 ~ scene_NN.mp4 的文件(即 scene_ + 正好2位数字 + .mp4) 2. 排除 任何带有额外后缀的文件(如 scene_01_1.mp4、scene_02_backup.mp4) 3. 按场景编号从小到大排序(数字排序,非字典序):scene_01, scene_02, ..., scene_09, scene_10, scene_11, ...
构建精确文件列表(按场景编号逐一构建,不扫描目录):
file_list = [
f"{videos_dir}/scene_{i:02d}.mp4"
for i in range(1, scene_count + 1)
]确认所有文件:
- 每个文件都存在且非空(
scene_01.mp4~scene_{N:02d}.mp4精确匹配) - 文件数量恰好等于 scene_count(不多不少)
- 无重复文件(每个 scene 编号只取一个文件)
若有文件缺失或损坏,立即报告,等待用户指示(不得跳过或省略任何场景)。
第二步:按顺序合并所有视频
python scripts/video_merge.py --input-dir "<videos_dir>" --output "<final_dir>/<task_name>_final.mp4" --scene-count <N>严格按 scene_01 → scene_02 → ... → scene_N 顺序合并。
等待合并完成,确认:
- 输出文件存在且文件大小 > 0
- 实际总时长由 ffprobe 自动检测(因每段视频时长不同,范围 4~15 秒)
- 预期总时长 ≈ sum(scene_durations) 秒(允许 ±5秒 误差)
第三步:上传到 TOS
python scripts/tos_upload.py "<final_dir>/<task_name>_final.mp4"记录返回的 TOS 签名 URL(完整保留,不得修改任何字符)。
tos_upload.py 返回 JSON 格式:
{"signed_url": "https://tos-cn-beijing.volces.com/...?X-Tos-Security-Token=..."}第四步:保存最终交付文档
python scripts/task_manager.py save "<task_folder>" "final_video.md" "<content>"内容格式:
# 最终视频
**任务名称**:{task_name}
**生成时间**:{timestamp}
**实际总时长**:{actual_duration} 秒({actual_duration / 60:.1f} 分钟)
**场景数**:{scene_count}
**时长分配**:{scene_durations}
## TOS 访问链接(7天有效)
{tos_signed_url}
## 本地文件路径
{final_dir}/{task_name}_final.mp4
## 分镜视频路径
{videos_dir}/scene_01.mp4 ~ scene_{N:02d}.mp4第五步:交付最终结果
必须向用户展示以下完整交付内容(不仅仅是文件路径,要让用户完整回顾全流程产出):
🎬 漫剧生成完成!
---
🎬 **最终视频**(⚠️ **必须使用 `<video>` 标签展示,禁止使用纯文本 URL、Markdown 代码块包裹的 URL 或 Markdown 链接格式**):<video src="{tos_signed_url}" width="640" controls>完整漫剧视频</video>
🔗 **TOS 访问链接**(纯文本备用):{tos_signed_url}
**本地保存路径**:{final_dir}/{task_name}_final.mp4
---
📋 **内容概要**:
- 实际总时长:{actual_duration} 秒(约 {actual_duration / 60:.1f} 分钟)
- 场景数:{scene_count}
- 时长分配:{scene_durations}(每段 4~15 秒动态分配)
- 视觉风格:{visual_style}
- 音频:✅ 含中文对白语音 + 背景音乐 + 音效
📖 **全流程关键产出回顾**:
| 环节 | 核心产出 |
|-----|---------|
| 剧本生成 | {scene_count} 章剧本,核心冲突:{一句话} |
| 角色设计 | {N} 个角色,风格:{visual_style} |
| 场景美术 | {scene_count} 张分镜图 |
| 分镜视频 | {scene_count} 段视频,总时长 {sum}秒 |
| 视频合成 | 完整漫剧 {actual_duration}秒 |
🖼️ **封面图**(⚠️ 使用 TOS URL):!漫剧封面
📁 **任务目录结构**:
{task_folder}/
├── requirements.md ✅ 需求文档(含调研摘要)
├── plot.md ✅ 章节式剧情大纲(含时长分配)
├── script.md ✅ 完整对白剧本(含逐秒时间戳 + 智能时长)
├── characters.md ✅ 角色设计(含立绘图片)
├── cover.jpg ✅ 封面图
├── storyboard/ ✅ ({scene_count} 张分镜图)
├── characters/ ✅ ({N} 张角色立绘)
├── videos/ ✅ ({scene_count} 段分镜视频,4~15s 智能时长)
└── final/ ✅ 完整合成漫剧
❌ **错误示例(禁止使用)**:
- ~~```text\nhttps://...\n```~~(代码块包裹 URL)
- ~~[视频链接](https://...)~~(Markdown 链接)
- ~~https://...~~(纯文本 URL 作为唯一展示方式)质量标准
- 合并顺序严格为 scene_01 → scene_02 → ... → scene_N,不得乱序
- TOS URL 必须完整传达给用户,禁止截断或省略签名参数
- 若 video_merge.py 报告失败,报告具体错误信息,不得用任何变通方案替代
- 实际总时长通过 ffprobe 检测,不再使用硬编码计算
- 每段视频时长范围为 4~15 秒,总时长 = sum(scene_durations)
- 所有图片或视频 URL 在输入输出的全流程中均需严格保持原始状态,不允许进行任何形式的篡改(包括但不限于修改域名、路径、query参数、锚点等)。
"""
漫剧应用配置工具
读取环境变量 VIDEO_DURATION_MINUTES,输出 JSON 配置。
智能时长模式:每个分镜根据场景复杂度动态分配 4s ~ 15s 时长。
用法:
python scripts/app_config.py
"""
import json
import os
SUPPORTED_DURATIONS = (0.5, 1, 2, 3, 4)
# 动态时长范围:每个分镜可分配 4s ~ 15s
MIN_SCENE_DURATION = 4
MAX_SCENE_DURATION = 15
def get_app_config() -> dict:
raw = os.environ.get("VIDEO_DURATION_MINUTES", "0.5").strip()
try:
minutes = float(raw)
except ValueError:
minutes = 0.5
if minutes not in SUPPORTED_DURATIONS:
minutes = 0.5
# 智能时长模式:总时长 = minutes * 60 秒
# 每个分镜可动态分配 4s ~ 15s,节奏更丰富多变
total_seconds = int(minutes * 60)
# 场景数参考范围:全用最长时长为下限,全用最短时长为上限
min_scenes = total_seconds // MAX_SCENE_DURATION # 全用15s时的场景数
max_scenes = total_seconds // MIN_SCENE_DURATION # 全用4s时的场景数
# 推荐场景数:以平均8s估算,兼顾节奏多样性
avg_duration = (MIN_SCENE_DURATION + MAX_SCENE_DURATION) / 2
recommended_scenes = round(total_seconds / avg_duration)
return {
"video_duration_minutes": minutes,
"total_seconds": total_seconds,
"smart_duration": True,
"duration_range": {"min": MIN_SCENE_DURATION, "max": MAX_SCENE_DURATION},
"duration_options": "4s ~ 15s 动态分配(4/5/6/7/8/9/10/11/12/13/14/15)",
"scene_count_range": {"min": min_scenes, "max": max_scenes},
"recommended_scene_count": recommended_scenes,
"note": "每个分镜时长根据剧情节奏动态决定:紧张快切4-6s,标准叙事7-10s,高潮铺垫11-15s",
"config_source": f"VIDEO_DURATION_MINUTES={raw}",
}
if __name__ == "__main__":
config = get_app_config()
print(json.dumps(config, ensure_ascii=False, indent=2))
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
批量并行图片生成工具。
将多个 prompt 并行提交给 AI 图片生成 API,显著提升多张图片生成速度。
支持指定输出目录和自定义文件名前缀。
环境变量:
MODEL_IMAGE_API_KEY or ARK_API_KEY or MODEL_AGENT_API_KEY: Ark API key (required)
MODEL_IMAGE_NAME: Image model name (optional, default: doubao-seedream-4-5-251128)
用法:
# 从 JSON 文件读取 prompts 列表,并行生成
python scripts/batch_image_generate.py --prompts-file prompts.json --output-dir <dir> [--prefix scene_] [--max-workers 3]
# 直接传入 prompt 列表(适合少量任务)
python scripts/batch_image_generate.py --prompts "prompt1" "prompt2" "prompt3" --output-dir <dir>
"""
import argparse
import base64
import json
import os
import sys
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import Optional
from volcenginesdkarkruntime import Ark
# Default model
DEFAULT_MODEL = "doubao-seedream-4-5-251128"
# 最大并行数(避免 API rate limit)
DEFAULT_MAX_WORKERS = 3
def _get_client() -> Ark:
api_key = (
os.getenv("MODEL_IMAGE_API_KEY")
or os.getenv("ARK_API_KEY")
or os.getenv("MODEL_AGENT_API_KEY")
)
if not api_key:
print(
"Error: MODEL_IMAGE_API_KEY, ARK_API_KEY or MODEL_AGENT_API_KEY environment variable is required."
)
sys.exit(1)
return Ark(api_key=api_key)
def _generate_single(
client: Ark,
model: str,
prompt: str,
output_dir: str,
filename: str,
index: int,
max_retries: int = 3,
) -> dict:
"""生成单张图片,支持自动重试。
Args:
client: Ark client
model: 模型名称
prompt: 提示词
output_dir: 输出目录
filename: 目标文件名(如 scene_01.jpg)
index: 图片索引(用于日志)
max_retries: 最大重试次数
Returns:
dict: {"index": int, "status": "success"|"failed", "filepath": str, "filename": str, "error": str}
"""
filepath = os.path.join(output_dir, filename)
for attempt in range(1, max_retries + 1):
try:
response = client.images.generate(
model=model,
prompt=prompt,
response_format="b64_json",
)
if response.data and response.data[0].b64_json:
img_bytes = base64.b64decode(response.data[0].b64_json)
with open(filepath, "wb") as f:
f.write(img_bytes)
print(f"[{index + 1}] ✅ 生成成功: {filename}")
return {
"index": index,
"status": "success",
"filepath": filepath,
"filename": filename,
"error": None,
}
elif response.data and response.data[0].url:
# Fallback: 下载 URL
import urllib.request
urllib.request.urlretrieve(response.data[0].url, filepath)
print(f"[{index + 1}] ✅ 生成成功(URL 下载): {filename}")
return {
"index": index,
"status": "success",
"filepath": filepath,
"filename": filename,
"error": None,
}
else:
raise ValueError("响应中无 b64_json 或 url")
except Exception as e:
error_msg = str(e)
print(
f"[{index + 1}] ⚠️ 第 {attempt}/{max_retries} 次尝试失败: {filename} - {error_msg}"
)
if attempt < max_retries:
# 指数退避等待
wait_time = 2**attempt
print(f"[{index + 1}] 等待 {wait_time}s 后重试...")
time.sleep(wait_time)
# 所有重试都失败
print(f"[{index + 1}] ❌ 全部失败: {filename}")
return {
"index": index,
"status": "failed",
"filepath": filepath,
"filename": filename,
"error": error_msg,
}
def _simplify_prompt(prompt: str) -> str:
"""简化 prompt,移除可能导致内容安全拒绝的高风险词汇。"""
replacements = {
"blood": "spiritual energy",
"bloody": "intense",
"bleeding": "glowing with energy",
"sword piercing": "sword energy clash",
"killing": "defeating",
"dead body": "fallen warrior",
"corpse": "motionless figure",
"explosion": "energy eruption",
"war": "confrontation",
"battle": "encounter",
}
simplified = prompt
for old, new in replacements.items():
simplified = simplified.replace(old, new)
return simplified
def batch_image_generate(
prompts: list[str],
output_dir: str,
prefix: str = "scene_",
ext: str = ".jpg",
max_workers: int = DEFAULT_MAX_WORKERS,
max_retries: int = 3,
filenames: Optional[list[str]] = None,
) -> dict:
"""批量并行生成图片。
Args:
prompts: 提示词列表
output_dir: 输出目录
prefix: 文件名前缀(默认 scene_)
ext: 文件扩展名(默认 .jpg)
max_workers: 最大并行数
max_retries: 每张图片最大重试次数
filenames: 自定义文件名列表(如 ["scene_01.jpg", "scene_02.jpg"]),
如果提供则忽略 prefix 和 ext
Returns:
dict: 批量生成结果
"""
if not prompts:
return {"status": "error", "message": "prompts 列表为空", "results": []}
os.makedirs(output_dir, exist_ok=True)
# 确定文件名列表
if filenames and len(filenames) == len(prompts):
names = filenames
else:
names = [f"{prefix}{i + 1:02d}{ext}" for i in range(len(prompts))]
client = _get_client()
model = os.getenv("MODEL_IMAGE_NAME", DEFAULT_MODEL)
print(f"🎨 开始批量生成 {len(prompts)} 张图片(并行度: {max_workers})...")
start_time = time.time()
results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {}
for i, (prompt, name) in enumerate(zip(prompts, names)):
future = executor.submit(
_generate_single,
client,
model,
prompt,
output_dir,
name,
i,
max_retries,
)
futures[future] = i
for future in as_completed(futures):
result = future.result()
results.append(result)
# 按 index 排序
results.sort(key=lambda x: x["index"])
elapsed = time.time() - start_time
succeeded = [r for r in results if r["status"] == "success"]
failed = [r for r in results if r["status"] == "failed"]
# 对失败的任务,尝试用简化 prompt 再次生成
if failed:
print(f"\n🔄 尝试对 {len(failed)} 个失败任务使用简化 prompt 重试...")
retry_results = []
with ThreadPoolExecutor(max_workers=max_workers) as executor:
retry_futures = {}
for r in failed:
idx = r["index"]
simplified = _simplify_prompt(prompts[idx])
future = executor.submit(
_generate_single,
client,
model,
simplified,
output_dir,
r["filename"],
idx,
2, # 简化 prompt 只重试 2 次
)
retry_futures[future] = idx
for future in as_completed(retry_futures):
result = future.result()
retry_results.append(result)
# 更新结果
for retry_r in retry_results:
if retry_r["status"] == "success":
# 替换原失败结果
for i, r in enumerate(results):
if r["index"] == retry_r["index"]:
results[i] = retry_r
break
# 重新统计
succeeded = [r for r in results if r["status"] == "success"]
failed = [r for r in results if r["status"] == "failed"]
summary = {
"status": "success" if not failed else "partial" if succeeded else "failed",
"total": len(prompts),
"succeeded": len(succeeded),
"failed": len(failed),
"elapsed_seconds": round(elapsed, 1),
"results": results,
"saved_files": [r["filepath"] for r in succeeded],
"failed_indices": [r["index"] for r in failed],
}
print(
f"\n📊 批量生成完成: {len(succeeded)}/{len(prompts)} 成功,耗时 {elapsed:.1f}s"
)
return summary
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="批量并行图片生成")
parser.add_argument("--prompts-file", help="JSON 文件路径,包含 prompts 字符串数组")
parser.add_argument(
"--prompts", nargs="+", help="直接传入 prompt 列表(与 --prompts-file 二选一)"
)
parser.add_argument("--output-dir", required=True, help="图片保存目录")
parser.add_argument("--prefix", default="scene_", help="文件名前缀(默认 scene_)")
parser.add_argument("--ext", default=".jpg", help="文件扩展名(默认 .jpg)")
parser.add_argument(
"--max-workers",
type=int,
default=DEFAULT_MAX_WORKERS,
help=f"最大并行数(默认 {DEFAULT_MAX_WORKERS})",
)
parser.add_argument(
"--max-retries", type=int, default=3, help="每张图片最大重试次数(默认 3)"
)
parser.add_argument(
"--filenames-file",
help="JSON 文件路径,包含自定义文件名列表(可选)",
)
args = parser.parse_args()
# 读取 prompts
if args.prompts_file:
with open(args.prompts_file, "r", encoding="utf-8") as f:
prompts = json.load(f)
elif args.prompts:
prompts = args.prompts
else:
print("Error: 必须提供 --prompts-file 或 --prompts")
sys.exit(1)
# 读取自定义文件名
filenames = None
if args.filenames_file:
with open(args.filenames_file, "r", encoding="utf-8") as f:
filenames = json.load(f)
result = batch_image_generate(
prompts=prompts,
output_dir=args.output_dir,
prefix=args.prefix,
ext=args.ext,
max_workers=args.max_workers,
max_retries=args.max_retries,
filenames=filenames,
)
print(json.dumps(result, ensure_ascii=False, indent=2))
if result["status"] == "failed":
sys.exit(1)
"""
创建单个视频生成任务。
用法:
python scripts/create_video_task.py --prompt "<prompt>" [--duration 10] [--first-frame "<url>"] [--last-frame "<url>"]
"""
import argparse
import json
import logging
import os
import re
from typing import Optional
import requests
logger = logging.getLogger(__name__)
_VALID_DURATIONS = set(range(4, 16))
_API_URL = "https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks"
_MODEL = os.environ.get("DEFAULT_VIDEO_MODEL_NAME") or os.environ.get(
"MODEL_VIDEO_NAME"
)
def _get_auth() -> str:
api_key = os.environ.get("ARK_API_KEY", "") or os.environ.get(
"MODEL_AGENT_API_KEY", ""
)
return f"Bearer {api_key}"
def _strip_cli_flags(prompt: str) -> str:
return re.sub(r"\s*--\w+\s+\S+", "", prompt).strip()
def _build_content(
prompt: str,
first_frame_image_url: Optional[str],
last_frame_image_url: Optional[str],
) -> list:
content = []
if first_frame_image_url and last_frame_image_url:
content.append(
{
"type": "image_url",
"image_url": {"url": first_frame_image_url},
"role": "first_frame",
}
)
content.append(
{
"type": "image_url",
"image_url": {"url": last_frame_image_url},
"role": "last_frame",
}
)
elif first_frame_image_url:
content.append(
{
"type": "image_url",
"image_url": {"url": first_frame_image_url},
"role": "first_frame",
}
)
content.append({"type": "text", "text": _strip_cli_flags(prompt)})
return content
def create_video_task(
prompt: str,
duration_seconds: int = 10,
first_frame_image_url: Optional[str] = None,
last_frame_image_url: Optional[str] = None,
) -> str:
if duration_seconds not in _VALID_DURATIONS:
duration_seconds = 10
logger.info(f"Using video generation model: {_MODEL}")
headers = {"Content-Type": "application/json", "Authorization": _get_auth()}
payload = {
"model": _MODEL,
"content": _build_content(prompt, first_frame_image_url, last_frame_image_url),
"seed": -1,
"duration": duration_seconds,
"watermark": False,
}
try:
resp = requests.post(_API_URL, json=payload, headers=headers, timeout=30)
logger.info(
f"create_video_task status={resp.status_code} body={resp.text[:300]}"
)
resp.raise_for_status()
task_id = resp.json().get("id")
if not task_id:
raise ValueError(f"响应缺少 task_id: {resp.text}")
logger.info(f"任务已提交 task_id={task_id} duration={duration_seconds}s")
return task_id
except requests.exceptions.RequestException as e:
body = getattr(getattr(e, "response", None), "text", "")
raise Exception(f"提交视频任务失败: {e} | 响应: {body}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="创建视频生成任务")
parser.add_argument("--prompt", required=True, help="视频提示词")
parser.add_argument("--duration", type=int, default=10, help="时长(秒)")
parser.add_argument("--first-frame", default=None, help="首帧图片 URL")
parser.add_argument("--last-frame", default=None, help="尾帧图片 URL")
args = parser.parse_args()
task_id = create_video_task(
prompt=args.prompt,
duration_seconds=args.duration,
first_frame_image_url=args.first_frame,
last_frame_image_url=args.last_frame,
)
print(json.dumps({"task_id": task_id}, ensure_ascii=False))
Related skills
FAQ
What does the final delivery include?
A complete comic-drama video and a TOS link, with artifacts saved to COMIC_DRAMA_OUTPUT_DIR.
What are the five stages?
Screenplay creation, character design, storyboard image generation, storyboard video generation, and video compositing.