| name | love-video |
| description | Use when user asks to generate a love/memorial/birthday/anniversary/proposal video from photos. Guides an 8-step conversation that turns a folder of travel photos into a finished narrated video using AI image + video generation (Seedream + Vidu by default). Handles character portrait anchoring, scene templates, cost estimate, and resumable batch generation. |
love-video Skill
为不懂代码的用户生成情感向视频。通过 8 步对话完成:场景 → 素材 → 人物 → 画风 → 密钥 → 确认单 → 生成 → 交付。
激活条件
用户说类似以下任一:
- "帮我做个求婚视频 / 生日视频 / 纪念日视频"
- "把这些照片做成 AI 动画"
- "生成旅行回忆视频"
工作目录约定
除非用户指定,默认工作目录 = 照片文件夹的父目录 / love-video-{场景}-{日期}。
产物命名(从 scripts/naming.py 取,不要硬编码):
{workdir}/定妆图/{idx:02d}_{name}.png
{workdir}/视频/{idx:02d}_{name}.mp4
{workdir}/转场/{from:02d}to{to:02d}.mp4
{workdir}/成片.mp4
{workdir}/failures.log
8 步流程
Step 1 — 场景确认
识别用户说的场景类型(求婚/生日/纪念日/自定义)。未明确时问一句。
加载对应模板:Read references/scene-templates.md 找到章节,提取"开场 / 结尾 / 开场转场 prompt 模板"。
Step 2 — 收集素材
问用户:"照片文件夹路径是什么?"
扫描目录(ls -la 或 Glob),列出所有图片文件,按 EXIF DateTimeOriginal 排序。没有 EXIF 的按文件名排序。
展示: 编号的地点名 + 缩略图路径,请用户确认顺序或给出调整("把 3 和 5 互换"、"删掉 8")。
用户确认后,把每张照片映射为 Scene dict:
{"idx": int, "name": str, "portrait_prompt": "", "video_prompt": "", "refs": [Path(原照片)]}
Step 3 — 人物形象
检测照片文件夹是否有 卡通形象/ 子目录:
- 有 → 展示里面的图 → "这是要用的卡通形象吗?"
- 没有 → 问:"你想要卡通风格(推荐)还是真实照片风格?"
- 卡通 → 让用户提供 1-3 张两人合照 → 调
image_gen.generate 生成 Q 版男生头像和女生头像,存到 卡通形象/男生.png、卡通形象/女生.png → 展示确认
- 真实 → 后续所有场景
refs 用原照片,画风自动切到 realistic
Step 4 — 画风 & 比例 & 时长
Read references/style-presets.md,展示 6 个选项。默认 q-kawaii。
问用户:
- 画风?(默认 q-kawaii)
- 比例?(16:9 横屏 / 9:16 竖屏,默认 16:9)
- 单段时长?(默认 5s)
把选择写到 cfg["preferences"]。
Step 5 — 密钥检查
from love_video.scripts import config
cfg = config.load_config()
avail = config.list_available_services(cfg)
如果 avail["image"] 或 avail["video"] 为空:
Read references/service-api.md 提示 Seedream / Vidu 的 Key 获取链接
- 让用户提供 Key,调
config.set_service_key(...) 保存
- 跑
config.check_connectivity(...) 验证
Step 6 — 确认单
组装最终 scenes 列表 + transitions 列表:
scenes[i].portrait_prompt = 画风.prompt_prefix + 画char_specs + "\n" + 场景描述
scenes[i].video_prompt = 场景动态描述
transitions[i].prompt = 用 scene-templates.md 的通用骨架填 from/to 场景
计算费用(参考 service-api.md 的公式)。
展示给用户(必须):
- 场景数 / 时长 / 画风 / 比例
- 预估费用(图像 + 视频 + 转场)
- 预估时间(每段约 1-2 分钟,16 段约 30-45 分钟)
等用户说"开始"才继续。
Step 7 — 生成
调 pipeline.run(workdir, scenes, transitions, cfg)。
pipeline 会:
- 逐个生成定妆图(已存在跳过,失败重试 1 次后记 failures.log)
- Checkpoint: 所有定妆图完成后,展示给用户审核(硬性规则 1,不可跳过),用户可指定"重做 03 和 07",你删除对应文件然后重新调
generate_portraits
- 逐个生成主视频
- 逐个生成转场
- ffmpeg 拼接成片
实时报告进度:每完成一段打印一行。
Step 8 — 交付
pipeline.run 返回成片路径。报告:
- 路径
- 文件大小(MB)
- 时长(用
ffprobe 取)
- 如有
failures.log 内容,展示出来
提示:"建议用剪映/CapCut 加 BGM 和字幕;成片当前无音轨。"
硬性规则(不可违反)
- 定妆图必须审核 — 生成完定妆图后必须停下来让用户看,不可直接进下一步
- 开跑前必须展示预估费用
- 失败自动重试 1 次(pipeline 已实现校验),仍失败写
failures.log,不阻塞
- 成片小于 1MB 视为失败(pipeline 已实现校验)
- 产物存在即跳过 —— 断点续跑;重做只需删除对应文件
调用 Python 脚本
scripts/ 不是独立 CLI,是库。在 Bash 里这样调:
cd /path/to/love-video
python3 -c "
import sys; sys.path.insert(0, '.')
from scripts import config, pipeline
cfg = config.load_config()
scenes = [...] # 从对话构造
transitions = [...]
pipeline.run('/path/to/workdir', scenes, transitions, cfg)
"
或者在对话里构造完 scenes/transitions 后把它们 Write 到 {workdir}/_run.py 再 python3 _run.py。
故障处理
- 密钥失效 →
check_connectivity 返回 False → 让用户重新填 Key
- 单段生成 NSFW 拒绝 → 记 failures.log → 用户可修改 prompt 重跑(删除文件)
- ffmpeg 未安装 →
which ffmpeg 报错 → 提示用户 brew install ffmpeg
- 成片卡顿/跳帧 → concat 需要各段编码一致;若跳帧,提示用户用
ffmpeg -c:v libx264 重编码(不在首版范围内)