心理学火柴人视频生成
把一个心理学主题,自动变成一支可发布的「黑色火柴人」风格短视频素材包。复刻自 Coze 工作流 X74,但完全脱离 Coze、可在本地/本 agent 复用。
产出物
一个项目文件夹,含:
project.json—— 时间线清单(标题、分镜、每帧图/音频路径、字幕逐句时间轴)。是后续渲染与导入剪映的"真相源"。scenes/*.png—— 每个分镜的黑白火柴人图(生成时多为 1280×720,渲染时统一放大到 1080p)。scenes/cover.png—— 封面/标题卡(可选,由scripts/generate_cover.py生成;render_video.py --cover将其作为片头前置,可带开场白配音)。<主题>_火柴人.mp4—— 最终成片(必产出):1920×1080 / 30fps / H.264,分镜间叠化转场,底部烧录逐句字幕,已混入配音音轨。audio/*.mp3—— 每帧配音(默认火山引擎方舟豆包 TTS,失败时自动回退 edge-tts)。draft_content.json/draft_meta.json—— 剪映草稿(实验性,见references/capcut_draft.md)。
工作流(7 步)
1. 收集输入
向用户确认(或设定默认值):
title:心理主题,如「为什么我们总在深夜 emo」。left_top/right_top:画面左上/右上角文字(栏目名 / 账号水印)。原工作流默认「心理学知识」和「@Codel」,换领域请改。脚本默认会把这两个角标自动叠加到每张火柴人图上(复刻原画板水印),不需要则传--no-watermark。image_engine:图像生成引擎,默认seedream(火山方舟,跨平台可用,与 TTS 共用 ark Key),可选agnes/gemini/dreamina/imagegen。若运行环境自带 ImageGen 工具(如 WorkBuddy),可改用imagegen零配置出图;其余引擎为纯 HTTP 接口,任何 agent 均可调用,详见第 4 步与references/image_providers.md。
2. 生成视频文案(大模型)
读取 references/prompts.md 的 ① 心理学视频文案 提示词,原样使用其中的 System/User Prompt 与模型参数(豆包 1.5 Pro 32k / temp 0.8 / JSON 模式)。把 {{title}} 替换为用户输入。
输出严格 JSON:
{ "title": "标题", "cap": "核心关键词", "content": "心理学科普正文" }
3. 生成分镜脚本(大模型)
读取 references/prompts.md 的 ② 分镜画面描述 提示词,把 {{content}} 替换为上一步的 content。输出 JSON 数组:
[
{ "story_name": "分镜名", "desc": "黑色火柴人分镜描述",
"cap": "该帧字幕文案", "desc_promopt": "英文黑白火柴人图像提示词" }
]
建议 8–15 个分镜,单视频 60–90 秒。注意:原工作流「循环」只跑 10 轮,分镜超过 10 个会丢帧,控制在 10 个左右最稳。
4. 生成火柴人图(图像引擎可指定,默认 seedream,跨平台可用)
视觉风格与提示词模板见 references/image_style.md——无论用哪个引擎,都必须套用该模板,否则风格跑偏。各引擎的鉴权/接口细节见 references/image_providers.md。
先确认第 1 步收集的 image_engine(默认 seedream):
seedream(默认):火山方舟 Seedream(与 TTS 共用ark-Key,无需额外 AK/SK),默认doubao-seedream-5.0-lite,可选 5.0-pro / 4.5 / 4.0:
```bash
# 默认 Doubao-Seedream-5.0-lite
python scripts/generate_images.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/scenes --engine seedream
# 切换为 5.0-pro
python scripts/generate_images.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/scenes --engine seedream --seedream-model doubao-seedream-5.0-pro
- **`agnes`**:Agnes AI 文生图(OpenAI 兼容),默认 `agnes-image-2.1-flash`,可 `--model` 切到 `agnes-image-2.0-flash`:bash
python scripts/generate_images.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/scenes --engine agnes --size 1280x720
- **`gemini`**:Google Gemini 3 Pro Image,需 `GEMINI_API_KEY`:bash
python scripts/generate_images.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/scenes --engine gemini
- **`dreamina`**:火山引擎即梦(需火山视觉 AK/SK,先 `pip install volcengine-python-sdk`):bash
python scripts/generate_images.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/scenes --engine dreamina --size 1280x720
- **`imagegen`(仅当运行环境自带 ImageGen 工具,如 WorkBuddy)**:用环境内置 `ImageGen` 工具,对每帧 `desc_promopt` 套模板生成 1920×1080 纯白底黑线火柴人图,存 `scenes/01.png`、`02.png`……(脚本 `generate_images.py` 不支持此引擎,因为它走内置工具而非 HTTP)。生图后请用 `scripts/add_watermark.py` 补左上角/右上角文字:bash
python scripts/add_watermark.py --scenes ./<主题>_video/scenes \
--left-top "心理学知识" --right-top "@Codel"
```
脚本会自动按 image_style.md 模板拼装提示词、逐帧调用引擎并命名 NN.png;除 imagegen 外,其余引擎在保存图片后会自动叠加 --left-top/--right-top 角标(与原工作流画板水印等价),也可用 --no-watermark 关闭。所有引擎输出都会被 render_video.py 放大到 1080p,最终成片观感一致。风格硬约束(务必遵守):仅黑白两色、clean lines、high contrast、极简、无阴影无彩色。
5. 生成配音(TTS,默认火山方舟豆包语音,edge-tts 为备选/自动回退)
用 generate_voiceover.py 为 project.json 每帧的 cap 生成配音,存到 audio/01.mp3、02.mp3……
# 默认:火山引擎「方舟 / 新版控制台」豆包语音(单一 API Key)
# Key 读取优先级:--volc-key 参数 > 环境变量 VOLC_API_KEY
# > 配置文件(依次尝试 ~/.config/psychology-video/volc_config.json、
# ~/.workbuddy/volc_config.json、项目本地 volc_config.json,
# 可用 PSYCH_VIDEO_CONFIG 环境变量指定):
# { "api_key": "<方舟 Key,供 Seedream 图像生成>",
# "tts_key": "<火山单 Key,供 TTS 语音合成>",
# "agnes_api_key": "<可选,Agnes 文生图 Key>",
# "resource_id": "seed-tts-2.0",
# "speaker": "zh_female_shuangkuaisisi_uranus_bigtts" }
# 默认引擎为 ark;该引擎失败时(如资源未开通 / 并发配额不足 / 音色与资源不匹配)会自动回退 edge-tts。
# 接口说明:实际调用 api/v3/tts/unidirectional(X-Api-Key 鉴权)。注意 api/v1/tts 是旧三件套
# 接口(需 appid/token),单 Key 模式不适用;seed-tts-2.0 资源仅接受以 _uranus_bigtts
# 结尾的 2.0 音色(如 zh_female_shuangkuaisisi_uranus_bigtts),不能用 1.0 的 zh_female_doubao。
# ark- 前缀 Key(方舟平台专属)走 /plan/tts/unidirectional;其余单 Key 走 /v3/tts/unidirectional。
python scripts/generate_voiceover.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/audio --engine ark
# 加快语速(1.2x,知识类短视频常用):ark / volcano 引擎支持 --speed
python scripts/generate_voiceover.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/audio --engine ark --speed 1.2
# 备选 / 纯微软 edge-tts(免费,无密钥),中文常用 XiaoxiaoNeural(女) / Yunxi(男)
python scripts/generate_voiceover.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/audio --engine edge --voice zh-CN-XiaoxiaoNeural
# 火山引擎「旧版控制台」TTS(需 app_id + token + cluster 三件套环境变量)
# VOLC_APP_ID / VOLC_APP_TOKEN / VOLC_CLUSTER(默认 volcano_tts) / VOLC_VOICE(默认 zh_female_doubao)
python scripts/generate_voiceover.py --project ./<主题>_video/final/project.json \
--out-dir ./<主题>_video/audio --engine volcano
- 默认火山 ark(豆包语音 2.0):音色更接近真人主播;用单一 API Key 调用
api/v3/tts/unidirectional(X-Api-Key 鉴权),资源固定seed-tts-2.0。脚本按 Key 形态自动路由:ark-前缀 Key → 方舟语音接入点/plan/tts/unidirectional;其余单 Key → 旧版/v3/tts/unidirectional。⚠️ 关键约束:① 用的是 v3 接口(/api/v1/tts是旧三件套接口,单 Key 不适用);②seed-tts-2.0资源只能用 2.0 音色(以_uranus_bigtts结尾,如默认zh_female_shuangkuaisisi_uranus_bigtts),不能用 1.0 的zh_female_doubao(会报resource ID is mismatched);③ TTS 的 Key 与 Seedream 图像的 Key 分开存(tts_keyvsapi_key)。若账号未开通/订阅语音合成模型会返回resource not granted;并发额度为 0 会报quota exceeded。当 ark 因上述原因失败时,脚本会自动回退 edge-tts 并仅提示一次失败原因,保证成片仍有声音。 - 备选 edge-tts:免费、联网即用、无需密钥,中文发音自然,最适知识类博主;作为 ark 的自动回退与手动备选。
- 配音时长通常短于分镜时长,渲染时会按分镜起点对齐、余下静音补齐,不会串帧。
6. 组装时间线
把分镜清单写成 storyboard.json(scene 的 image/audio 填实际路径,duration 缺省用 default_scene_duration),运行脚本生成 project.json:
# 基础:组装时间线(--capcut 额外生成剪映草稿)
python scripts/build_draft.py --input storyboard.json --out ./<主题>_video/final --capcut
# 带封面:片头前置封面帧(封面图由 generate_cover.py 生成;--cover-cap 让封面开口说话)
python scripts/build_draft.py --input storyboard.json --out ./<主题>_video/final \
--cover-image scenes/cover.png --cover-cap "今天我们来聊聊<主题>" --cover-duration 3
storyboard.json 结构(务必保留 desc_promopt,否则生成图像时没有英文提示词;desc 作为兜底):
{
"title": "标题", "theme": "主题",
"resolution": [1920, 1080], "fps": 30,
"bg_image": null, "default_scene_duration": 6.0,
"scenes": [
{"story_name":"开场","cap":"字幕文案",
"desc_promopt":"English black-and-white stick-figure prompt for this scene",
"image":"scenes/01.png","audio":"audio/01.mp3","duration":6.0}
]
}
脚本复刻原工作流「代码」节点逻辑:图片按 duration 顺序铺放、字幕按 ,。! 切分并均分时长;并原样透传每帧的 desc_promopt / desc 到 project.json(供 generate_images.py 取英文提示词出图,无需手动合并)。--cover-* 会在片头插入一个 is_cover 封面帧(index=-1),generate_images.py 会自动跳过它。输出 project.json,--capcut 时额外输出剪映草稿。
7. 渲染成片(必产出 mp4,含配音)
用 render_video.py 把 project.json 渲染成可播放 mp4——分镜间叠化(fade)转场,逐句字幕烧录到画面底部(ASS 字幕,避免中文引号坑),并通过 --audio-dir 混入配音音轨,还可叠加 --bgm 背景音乐(循环铺满、自动降音量,不压人声)。ImageGen 实际出图多为 1280×720,脚本会 scale 放大到 1920×1080。
节奏由真实配音时长驱动(避免空档/错位):每帧 duration_sec = max(语音真实时长 + 转场重叠 + 停顿, 最小分镜时长),字幕窗口按字数比例映射到真实语音时间轴,跟住配音。--cover 指定封面时,若 project.json 含 index=-1 的封面帧且其 cap 非空,封面会在片头开口说话。
# 配音版(节奏由真实语音驱动,字幕跟住配音)
python scripts/render_video.py --project ./<主题>_video/final/project.json \
--out ./<主题>_video/final/<主题>_火柴人.mp4 --font "SimHei" \
--audio-dir ./<主题>_video/audio
# 推荐成片:封面 + 程序化转场音效 + 分镜间轻停顿
python scripts/generate_cover.py --title "主题" --subtitle "一句副标题" \
--out ./<主题>_video/scenes/cover.png
python scripts/render_video.py --project ./<主题>_video/final/project.json \
--out ./<主题>_video/final/<主题>_火柴人.mp4 --font "SimHei" \
--audio-dir ./<主题>_video/audio \
--cover ./<主题>_video/scenes/cover.png --cover-duration 3 --sfx
# 配音 + 背景音乐
python scripts/render_video.py --project ./<主题>_video/final/project.json \
--out ./<主题>_video/final/<主题>_火柴人.mp4 --font "SimHei" \
--audio-dir ./<主题>_video/audio \
--bgm ./<主题>_video/bgm.mp3 --bgm-volume 0.25
- 需要 ffmpeg:脚本优先用
imageio-ffmpeg(pip install imageio-ffmpeg),否则取 PATH 中的ffmpeg。 - 字幕字体默认
SimHei(Windows 自带);其他系统可换Noto Sans CJK SC等。 - 输出:1920×1080 / 30fps / H.264,含 AAC 配音音轨,时长 ≈ 各分镜时长之和 −(分镜数−1)×转场时长。
- 节奏参数(配音驱动时长):
--overlap(转场重叠,默认 0.5s)、--pause(分镜间停顿,默认 0.4s)、--min-scene(单帧最短时长,默认 3.5s)。想更慢就调大--min-scene/--pause。 - 封面:
--cover <png>把封面前置为片头;--cover-duration(默认 3.0s)仅用于无配音的静默封面,配音封面由真实语音长驱动。封面帧在project.json中需为index=-1且带cap(由build_draft.py --cover-cap生成)。 - 转场音效:
--sfx用aevalsrc程序化生成轻柔 whoosh 转场音(无需任何素材文件);--sfx-volume(默认 0.15)建议低于配音。 --bgm-volume默认 0.25(25%),建议保持 0.15–0.30 之间,确保 BGM 不盖过人声。- 不传
--audio-dir则只出无声画面(向后兼容);也可只传--bgm出纯背景音乐版。
把素材包导入剪映(可选)
- 手动导入剪映(最稳):导入
scenes/图片 → 主轨按duration排、转场叠化 → 拖入audio/配音 → 按project.json的subtitles加字幕 → 导出 1080p。 - 剪映草稿自动导入(实验性):用
--capcut产物,剪映「导入草稿」打开。⚠️ 格式与客户端版本强绑定,失败则回落手动导入。 - 回 Coze 跑原工作流:若你有「剪映小助手数据生成器」+「视频合成_剪映小助手」插件,直接导入原 X74 工作流最省事。
关键提醒
- 两段大模型提示词必须原样使用,不要改写,它们决定内容质量与风格统一。
- 视觉风格一致性是核心:任何彩色/写实都会破坏"火柴人"观感。
- 图像引擎可在第 1 步用
image_engine指定(默认seedream,跨平台可用),备选agnes/gemini/dreamina;若运行环境自带 ImageGen 工具(如 WorkBuddy),也可选imagegen零配置出图。切换引擎不影响后续配音/渲染,因为所有引擎共用同一套黑白火柴人提示词模板(见references/image_providers.md)。 - 角标默认自动叠加,复刻原工作流画板的左上/右上角文字;若用
imagegen引擎(需运行环境自带 ImageGen 工具,如 WorkBuddy),请单独运行scripts/add_watermark.py补角标。 - 配音默认用火山方舟豆包语音(配置单一 API Key 即可,见配置文件
~/.config/psychology-video/volc_config.json或~/.workbuddy/volc_config.json或--volc-key);该通道因额度受限失败时自动回退 edge-tts,无需手动切换。
跨 agent / 多平台使用
本技能为纯 Python 脚本 + 标准 HTTP 接口 + ffmpeg,可在任意支持运行 Python 与 ffmpeg 的智能体(WorkBuddy / OpenClaw / Codex / Trae Work 等)中复用,不绑定特定平台:
- 图像引擎:
seedream/agnes/gemini/dreamina均为纯 HTTP 接口,任何 agent 都能调用;仅imagegen依赖运行环境自带的 ImageGen 工具(如 WorkBuddy),其它 agent 请改用上述 HTTP 引擎。 - 密钥配置:脚本会依次在以下位置查找
volc_config.json(可用环境变量PSYCH_VIDEO_CONFIG指定):~/.config/psychology-video/volc_config.json→~/.workbuddy/volc_config.json(兼容 WorkBuddy)→ 项目本地volc_config.json;也支持--volc-key/ 各引擎的环境变量(VOLC_API_KEY、AGNES_API_KEY、GEMINI_API_KEY等)。脚本内不再硬编码任何密钥,分发前请确保密钥只存在于你自己的配置文件。 - 字幕字体:
render_video.py未指定--font时按系统自动探测中文字体族名(Windows: SimHei / macOS: PingFang SC / Linux: Noto Sans CJK SC),跨平台字幕不乱码。 - 运行依赖:首次使用请
pip install Pillow edge-tts certifi imageio-ffmpeg(dreamina 额外需volcengine-python-sdk),并确保有 ffmpeg(系统安装或imageio-ffmpeg)。