从一句主题到成片,全程零实拍。 本文是「照着敲就能跑」的操作手册,含每步命令、预期产物、避坑点。
cd skill-mv
fmode-mv doctor # node / ffmpeg / 凭据 / 通道
fmode-mv providers # 能力现状(哪条通道能用)
开工前必须知道:截至 v0.1.0,平台只有 chat(文案) 与 image(关键帧) 两条通道开通。
music / video / lipsync 未开通。这不是技能的问题,是网关渠道的问题。
处理方式见 references/capability-matrix.md,本文每步都标了「通道不通时怎么办」。
① 作曲填词 [chat ✅] → work/song.json
② 分镜脚本 [chat ✅] → work/storyboard.json
③ AI 音乐 [music ❌] → work/audio/music.mp3(未开通,可自备音频)
④ 音轨分离 [本地 ◐] → work/audio/vocals.wav + instrumental.wav
⑤ 人物资产 [即梦 ✅] → out/character/{1-定妆照,2-上半身,3-全身,4-多视图}.png ★v0.2新增
⑥ 场景图+关键帧 [即梦 ✅] → work/scene/shot-XX.png(无人)+ work/frames/shot-XX.png(有人)★v0.2
⑦ 图生视频 [即梦 ✅] → work/clips/shot-XX.mp4(真 AI 生成) ★v0.2
⑧ 唇形驱动 [lipsync ❌] → 可用即梦数字人替代
⑨ 剪辑合成 [本地 ✅] → out/mv.mp4
一条命令跑完全程:
fmode-mv song "深夜末班地铁上的城市白领" --genre "city pop" --mood "孤独但温暖"
下面逐步拆解,方便分段调试与省钱。
fmode-mv lyrics "深夜末班地铁上的城市白领,加班后的疲惫与微小的温暖" \
--genre "city pop" \
--mood "孤独但温暖"
产物 work/song.json:
{
"title": "末班车还亮着",
"genre": "城市流行 City Pop",
"mood": "孤独、温暖、夜色、治愈",
"bpm": 92,
"structure": ["Intro","Verse 1","Pre-Chorus","Chorus", ...],
"lyrics": "[Intro]\n(器乐)\n\n[Verse 1]\n写字楼的灯 一盏一盏熄了\n...",
"stylePrompt": "city pop, 92 bpm, warm analog synth pads, electric piano chords, ... female vocal ..."
}
要点:
structure 的结构标记是给音乐模型的分段指令,不要删——Suno 类模型靠它排段落。stylePrompt 是英文的,直接投给音乐模型;改曲风就改这里。! 歌词自检提示:...,据此重跑或手改 JSON。避坑:
--style "控制在 2 分 30 秒,副歌重复 3 次"。fmode-mv storyboard --from work/song.json --shots 8 --per-shot 6
产物 work/storyboard.json(下游全部消费它)+ work/storyboard.md(人读版表格)。
关键字段:
| 字段 | 作用 |
|---|---|
appearanceAnchor |
★主角外貌锚点(英文)。每个含人物的镜头都会原样复述它 → 人物一致性全靠这个 |
styleKeywords |
全片统一影像风格,拼进每张关键帧 prompt |
shots[].imagePrompt |
英文,可独立投喂文生图 |
shots[].videoPrompt |
英文运镜描述,投给图生视频 |
shots[].lipSync |
是否做唇形驱动 |
避坑(实测踩过的):
--shots 为硬性约束、单镜钳制在 3~10 秒),且 normalizeStoryboard 会二次夹取。
若看到 ! N 个镜头的时长超出合理区间已被夹取,说明模型不听话,已被自动纠正。deepseek-v4-flash 会把大量 token 花在推理上,8192 token 全被推理吃掉、
JSON 被截断。技能已内置自动升配(翻倍重试到 24k~32k)+ 修复式重试。
若还失败,换非推理模型:--model doubao-seed-2-1-pro。appearanceAnchor,除非你同时接受整片人物变脸。
想换主角,改锚点后必须重生成全部关键帧。只做几镜试跑(省钱):
fmode-mv storyboard --from work/song.json --shots 3
fmode-mv keyframe --from work/storyboard.json --limit 3
fmode-mv music --from work/song.json
现状实测:POST /suno/submit/music 返回 503 Task request failed —— 端点存在,渠道未开通。
命令会真试一次,失败后给出可操作方案,不会伪造 mp3。
三条替代路线:
| 方案 | 做法 |
|---|---|
| A. 等平台开通 | 开通后原命令无需改动即可用 |
| B. 自备音乐 | 用你的音频直接进后续流程:--music your-song.mp3 |
| C. 对接外部 | export FEME_MUSIC_ENDPOINT=https://... 指向兼容端点 |
自备音乐时的注意:
assemble 会以画面轨时长为准,音频超出会被 -shortest 截断。fmode-mv separate work/audio/music.mp3
两级策略,脚本会自动选:
pip install demucs避坑:
vocals.wav 主要给第 ⑦ 步唇形驱动当驱动音频用;纯音乐 MV 其实可以跳过这步。fmode-mv character-sheet --desc "25岁东亚女性,栗棕色长直发,身穿米色针织开衫和白色长裙,清冷安静" --limit 1
fmode-mv character-sheet --desc "..." --limit 4 # 完整四步
四步流水线:① 定妆照(3候选) → ② 上半身 → ③ 全身 → ④ 多视图,每步图生图参考上一步 + 锐度自动择优。
产物 out/character/{1-定妆照,2-上半身,3-全身,4-多视图}.png + candidates/ + character-sheet.json。
为什么必须有这一步:纯 AI 出片最容易翻车的就是「同一人物跨镜头换脸」。
只靠 prompt 里的 appearanceAnchor 是软约束;有了多视图做图生图参考,才是像素级硬约束。
费用:--limit 1 ¥0.60(3 张候选);完整四步 ¥1.98(9 张候选)。--dry-run 零费用。
避坑:
--desc 里(如「身穿…」),否则会退回默认兜底并在日志里警告。--single 每步只出 1 张、跳过择优(省钱,但质量靠运气)。fmode-mv scene --from work/storyboard.json --character out/character/4-多视图.png
fmode-mv scene --from work/storyboard.json --shot 3 --limit 1 # 试跑
fmode-mv scene --from work/storyboard.json --scene-only # 只出场景图
两步法(v0.2 的核心改进):
[场景图, 人物多视图]。为什么拆两步:一次推理里同时解决空间/光线/人脸三件事,结果往往是背景每镜都不一样、 人物和背景光照打架。拆开后背景一致、光照统一。 相邻镜头还会把「上一镜场景描述」注入本镜 prompt 做一致性约束。
产物 work/scene/shot-XX.png + work/frames/shot-XX.png + work/scene/scenes.json。
费用:每镜 ¥0.42(场景图 ¥0.20 + 关键帧 ¥0.22)。
旧的
fmode-mv keyframe(走/v1/images/generations)保留可用,作为即梦不可用时的回退。
fmode-mv video --from work/storyboard.json # auto:走即梦真通道
fmode-mv video --from work/storyboard.json --limit 1 # 先试 1 镜(≈¥1.41)
fmode-mv video --from work/storyboard.json --mode still # 零费用:Ken Burns 兜底
实测:/getVideoV3_720p,121 帧(5 秒),实扣 ¥1.41,返回 h264 mp4(2.4MB)。
旧通道 /v1/video/generations 仍是 503,已由即梦替代。
--mode 三种模式:
| 模式 | 行为 |
|---|---|
auto(默认) |
探活;通就走即梦真通道,不通自动降级为 Ken Burns 兜底 |
jimeng |
只走即梦,不通即失败(用于强制验证) |
still |
强制用关键帧做 Ken Burns 运镜(零 API 费用) |
三条硬约束(v0.2 实测修正,KB 未记载):
frames 必须 ∈ {121,145,169,193,217,241}(既在 [121,241] 内,又要 ≡1 (mod 24))。
→ 单镜只能是 5/6/7/8/9/10 秒的整数秒。分镜阶段就按时长设计最省事。method=3(首尾帧)需要 2 张同比例图;第一镜用下一镜的关键帧作尾帧。method=3 失败会自动降级 method=2,返回带 degraded: true 并在日志写明(不静默)。避坑:
method=3(室内→室外、人物→空镜这类两帧会崩坏)——
硬规则:首尾帧只用于同场景连续动作 / 相似场景过渡 / 状态渐变。fmode-mv video --from work/storyboard.json --force。fmode-mv lipsync --probe # 先看通道状态
现状:网关没有 /lipsync/generations 这条路由(返回前端兜底页)。
v0.2 的替代(实测可用):
fmode-mv jimeng digital-human \
--ref out/character/3-全身.png \
--audio work/audio/vocals.wav \
--prompt "固定机位,头部随节奏轻微摆动,神情投入,眼神直视镜头"
走即梦数字人 v1.5 三步流程,¥1/秒,是真人对口型。
其余替代路线(按推荐度):
| 方案 | 做法 | 观感 |
|---|---|---|
| 即梦数字人 | 上面那条命令 | 最好(¥1/秒) |
| C. 纯空镜 + 字幕 | 不标 lipSync,全片走 B-roll |
纯音乐 MV 最常见,零风险 |
| B. 表情微动镜头 | 演唱镜头走图生视频(表情/头部微动),不严格对口型 | 成片观感可接受 |
| A. 自建服务 | 部 Wav2Lip / SadTalker / LatentSync,export FEME_LIPSYNC_ENDPOINT=... |
需部署 |
避坑:
lipSync: true 只对 perf/talking 类型生效,给 broll 标了也会被忽略。## 十、⑨ 剪辑合成 ✅
bash fmode-mv assemble \ --from work/storyboard.json \ --music work/audio/music.mp3 \ --beat-sync
**这一步做的事(全在本地 ffmpeg)**:
1. 按 `shot-XX` 序号收集片段(缺 `shot-XX.mp4` 时自动用 `shot-XX.fallback.mp4` 顶上)
2. 统一分辨率/帧率后拼接
3. `--beat-sync`:能量包络节拍检测 → 把镜头时长吸附到节拍点
4. 从分镜的 `subtitle` 字段生成 SRT,烧硬字幕
5. 混音(音乐 + 可选配音/背景乐),片尾淡出
6. 响度归一化到 I=-14 LUFS(两遍 loudnorm)
**产物**:`out/mv.mp4` + `out/manifest.json`(含兜底片段数、BPM、音轨信息)。
**避坑**:
- **卡点检测对纯音无效**。实测用正弦波测出「0 个节拍点」——
脚本会明确告诉你「未检出节拍点,跳过卡点对齐」,**不会假装对齐了**。
要卡点必须有鼓点/瞬态的成品编曲。
- **字幕字号自适应**:按分辨率算 `fontSize = h/36`,改分辨率不用手调。
- **字幕烧入失败不会中断成片**:会降级为「成片不带字幕,SRT 文件仍在 work/」并打印警告。
常见原因是字体缺失,装 `fonts-noto-cjk` 即可。
- 片段缺失或损坏时 `assemble` 会直接报错告诉你缺哪段,不会给你一个静默残缺的成片。
---
## 十一、端到端速查
bash
fmode-mv song "主题" --genre "city pop"
fmode-mv lyrics "主题" --genre "city pop" fmode-mv storyboard --from work/song.json --shots 6 fmode-mv keyframe --from work/storyboard.json --dry-run # 先看 prompt fmode-mv keyframe --from work/storyboard.json --shot 1 # 只做首镜 fmode-mv keyframe --from work/storyboard.json # 满意后批量 fmode-mv video --from work/storyboard.json # 自动兜底 fmode-mv assemble --from work/storyboard.json --music your-song.mp3 --beat-sync ```
开工前的三个好习惯:
--dry-run 看 prompt,别一上来就批量烧钱。--limit 2 跑通全链路,再放开全部。work/,不满意只重跑那一步,不用从头来。