Skip to main content

cinematic-music-video

把一首歌 + 歌词制作成电影级音乐 MV。先把主角按七个维度定全(三视图 / 五官特征 / 发型结构 / 服装层次 / 表情库 / 标志动作 / 场景气质),再把反复出现的地点定义成场景资产(scenes[] + 无人空镜锚点图),用 agnes-image-2.5-flash 生成「角色资产设定表」(大特写 + 正/侧/背三视图 + 表情带)与逐镜头首帧,用 agnes-3.0-flash 的视觉能力从真实图片反读结构化参数并做人物/场景一致性质检与自动重画,然后用 agnes-video-2.5-flash 图生视频,最后用 ffmpeg 按帧精确拼接并混入原声。保证人物一致性、地点一致性、情绪可控、原声一致性、不丢帧、图音同步、画布统一、镜头有真实运动。所有产物与中间产物统一输出到当前会话工作目录下的 out/(process.cwd()/out,不写回技能安装目录,可用 CMV_OUT_DIR 改根),源码不含任何机器相关绝对路径。Invoke when the user asks to make a music video / MV / 音乐视频 / 歌曲 MV from a song and lyrics.

ソース情報

リポジトリ
smart-open/skills
ソースの最終更新活動
2026年9月19日 06:53
検出された SKILL.md の言語
中国語
スター
12
フォーク
1

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
25 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
cinematic-music-video
description
把一首歌 + 歌词制作成电影级音乐 MV。先把主角按七个维度定全(三视图 / 五官特征 / 发型结构 / 服装层次 / 表情库 / 标志动作 / 场景气质),再把反复出现的地点定义成场景资产(scenes[] + 无人空镜锚点图),用 agnes-image-2.5-flash 生成「角色资产设定表」(大特写 + 正/侧/背三视图 + 表情带)与逐镜头首帧,用 agnes-3.0-flash 的视觉能力从真实图片反读结构化参数并做人物/场景一致性质检与自动重画,然后用 agnes-video-2.5-flash 图生视频,最后用 ffmpeg 按帧精确拼接并混入原声。保证人物一致性、地点一致性、情绪可控、原声一致性、不丢帧、图音同步、画布统一、镜头有真实运动。所有产物与中间产物统一输出到当前会话工作目录下的 out/(process.cwd()/out,不写回技能安装目录,可用 CMV_OUT_DIR 改根),源码不含任何机器相关绝对路径。Invoke when the user asks to make a music video / MV / 音乐视频 / 歌曲 MV from a song and lyrics.
agent_created
true
# 电影级音乐 MV 制作 (cinematic-music-video) 把「一首歌 + 歌词」变成一支电影质感的音乐 MV。整条流水线用 Agnes 三个模型分工: **agnes-3.0-flash 当导演兼质检**(分镜 + 人物视觉核验)、**agnes-image-2.5-flash 当摄影** (角色设定表 + 逐镜首帧)、**agnes-video-2.5-flash 让画面动起来**(图生视频),最后 **ffmpeg 做剪辑与混音**。 > **本版本的三处核心升级。** > > **其一:人物一致性从"靠祈祷"变成"有门禁"。** > 旧做法是「一张半身定妆照 → 派生全身照 → 逐镜头生成」,结果实测出现**首帧和定妆照明显不是同一个人**。 > 原因有四:半身照没有全身信息(模型只能编)、派生链是"复制品的复制品"(每过一手都掉精度)、 > 镜头是 16:9 远景而参考是 1:1 半身(尺度差太大)、身份描述被埋在长提示词中间(权重被稀释)。 > 现在改为:**一张角色设定表锁定真源 → 单独反读结构化参数 → 派生多角度白底参考图 → > 每张含主角的首帧都过一遍视觉一致性核验,不达标自动带着"差异清单"重画。** > > **其二:人物"先定清楚再进分镜"。** > 旧做法是规划器一边编剧情一边临时决定这个人穿什么、什么表情、在什么场景里—— > 结果"同一个人在每个镜头里都像刚被重新介绍了一遍"。 > 现在要求**在写任何镜头之前**,把主角按**七个维度**全部定死: > **三视图、五官特征、发型结构、服装层次、表情库、标志动作、场景气质**。 > 定完之后分镜就退化成"把已经定好的人放进已经定好的场景",跨镜头一致性也从"靠模型自觉" > 变成"靠结构保证"。详见 **1.1 七维度角色档案**。 > > **其三:地点也是资产,且身份被切成"不可变 / 本场可变"两桶。** > 三个镜头写在"同一个雨夜街头",就是三次独立生成——巷子宽窄、灯位、积水颜色都会漂, > 观众不会说"巷子变了",只会觉得"这不像一个片子"。现在**地点先在 `scenes[]` 里定义成资产**, > 系统为它生成一张**无人空镜锚点图**,该地点的所有镜头(含空镜)都挂上它(见 **2.4**)。 > 同时角色卡被拆成 **不可变身份**(骨相 / 发构 / 肤色)与 **本场可变**(服装 / 淋湿 / 擦伤 / 速度)两桶, > 分块注入——因为把"架构"和"天气"混成一段,就是换脸的起点(见 **2.2**)。 > **一致性 = 共享可复用资产 + 显式引用**,而不是"在提示词里重新描述一遍"。 > > **外加一条工程约束:产物与机器环境解耦。** > **所有结果与中间产物只写进当前会话工作目录下的 `out/`(`process.cwd()/out`),不写回技能安装目录**; > 源码内不含任何绝对路径、盘符、用户名或 `home` 目录,歌曲/歌词会被复制进项目使项目可整体搬走。 > 详见 **输出契约** 一节,由 `test/paths.js` 强制守住。 ## 何时调用 用户出现以下意图时调用本 Skill: - "给这首歌做个 MV / 音乐视频 / 音乐短片" - "根据歌词做一支电影感的视频" - 提供了歌曲文件 + 歌词,要求生成带音乐的成片 - 要求"图生视频 + 保持人物一致 + 不丢帧 + 图音同步"的 MV 类交付 ## 运行环境 | 依赖 | 要求 | 检查方式 | |---|---|---| | Node.js | ≥ 18(本机已有 22.x) | `node -v` | | ffmpeg / ffprobe | 必须可用,含 libx264 | `ffmpeg -version` | | Agnes API Key | 至少 1 个,推荐 2 个以上用于轮询 | 见下 | > 脚本**零 npm 依赖**,只用 Node 内置模块。 > Windows 下 ffmpeg 通常已在 PATH;若未安装:`winget install Gyan.FFmpeg`。 > ffmpeg 不在 PATH 时可用环境变量指定绝对路径:`FFMPEG=...` / `FFPROBE=...`。 > 若 bash 里 `cp/ls/head/tail/wc/sed/basename` 报 `command not found`(本机实测过的一种 PATH 劣化), > 执行前先补回 PATH(注意 `/c/Windows` 也要在,否则 `cp` 仍找不到): > `export PATH="/usr/bin:/bin:/c/Windows/System32:/c/Windows:$PATH"` ## 输出契约:一切都在当前会话的 `<cwd>/out/` 下 **这是硬约束,不是约定。** 所有结果输出与中间产物**只**写到**运行命令时的当前工作目录**下的 `out/`, 不写回技能安装目录;同一流水线的各阶段必须在**同一个 cwd** 下执行(或用 `CMV_OUT_DIR` 固定输出根)。 ``` <cwd>/out/ ← 唯一的输出根(跟随会话),可整体删除或打包 ├── .state/ # 跨项目共享的运行时状态 │ ├── .agnes-key-state.json # Key 轮询游标 │ └── vision-cache/ # 喂给视觉模型的降采样图缓存 ├── mv-<歌名>/ # 每首歌一个项目目录 │ └── 00_source/ … 05_output/ # 见「目录结构」 ``` **为什么这样设计**(对应两条硬性要求): | 要求 | 实现 | |---|---| | 产物集中、可整体清理 | 所有路径由 `lib/paths.js` 统一推导,输出根锚定当前会话 cwd(`<cwd>/out`) | | **不依赖本机环境**(绝对路径 / 用户名 / 盘符) | 源码内**零**硬编码绝对路径;`process.cwd()` 只允许出现在 `lib/paths.js`(锚定输出根),`test/paths.js` 会扫描源码强制这条 | 想换盘或挂到大容量目录时,**不要改代码**,用环境变量覆盖即可: ```bash CMV_OUT_DIR="/d/mv-out" node "<skill-dir>/scripts/run.js" --song "夜曲.mp3" --keys "sk-aaa" ``` > **项目目录现在是可搬走的。** `plan.js` 会把歌曲(以及歌词文件)复制进 `00_source/`, > 并在 `project.json` 里记录**相对项目目录**的路径。因此项目复制到另一台机器后, > `assemble.js` / `verify.js` 仍能找到原声,不会因为"用户把歌挪走了"而失败。 ## API Key 与轮询 Key 按优先级解析,**支持多个 Key 自动轮询**: 1. `--keys "sk-a,sk-b,sk-c"`(逗号/分号/空格分隔) 2. `--keys-file keys.txt`(每行一个,`#` 开头为注释) 3. `--api-key sk-x`(单个) 4. 环境变量 `AGNES_API_KEYS` → `agnes-api-key` → `AGNES_API_KEY` 轮询行为:**round-robin 游标持久化**在当前会话的 `out/.state/.agnes-key-state.json`,遇到 `401/403` 或 `429` 会把该 Key 打入冷却队列并自动切到下一个(冷却时长指数递增,上限 5 分钟);多个 Key 全部冷却时 会等待最早恢复的那个。每个阶段结束会打印各 Key 的成功调用次数。 游标是**跨项目共享**的,所以连续做多首歌时请求会持续在 Key 之间分散,而不是每首歌都从第 1 个 Key 重新开始。 > **安全**:不要把 Key 写进任何文件或日志。脚本只通过参数/环境变量读取,日志里只输出掩码。 ## 四阶段流水线 ``` plan.js → images.js → videos.js → assemble.js 七维度角色档案 设定表→反读参数→多角度参考→逐镜首帧 图生视频 精确拼接+混原声 + 地点资产库 + 地点空镜锚点 + 就绪预检 + 分镜铁律 (过身份门禁 + 身份/本场分块注入) + 一镜多拍选优 ↑___________________agnes-3.0-flash 视觉质检___________________↑ ``` **三类资产,全部"先行":** 角色(设定表 + 反读参数 + 多角度参考)、**地点**(无人空镜锚点)、 风格(基调板)。所有镜头只负责**引用**这些资产,而不是在提示词里重新描述一遍—— 这是一致性从"靠模型自觉"转为"靠结构保证"的关键。 一步跑完(可断点续跑,已完成的阶段自动跳过)。**无需指定输出目录**——默认就是 当前会话工作目录下的 `out/mv-<歌名>/`: ```bash node "<skill-dir>/scripts/run.js" \ --song "夜曲.mp3" \ --lyrics "夜曲.lrc" \ --brief "城市里两个人在雨夜重逢又告别" \ --style "霓虹雨夜,胶片质感,青橙色调" \ --aspect 16:9 --shots 26 \ --video-mode keyframe --motion-min 1.2 --motion-retries 2 \ --transition dissolve --fade --normalize-audio \ --concurrency 3 \ --keys "sk-aaa,sk-bbb" ``` 也可以分阶段执行,便于逐段审查(**推荐**,见下方"标准工作流")。 --- ## 阶段 1:分镜规划 `plan.js` ```bash # 默认输出到 <cwd>/out/mv-夜曲/;要换位置加 --out <dir> node "<skill-dir>/scripts/plan.js" \ --song "夜曲.mp3" \ --lyrics "夜曲.lrc" \ --brief "创作要求:一段关于城市夜晚重逢的故事" \ --style "赛博朋克霓虹" \ --aspect 16:9 --shots 26 \ --keys "sk-aaa,sk-bbb" ``` **它做什么** 1. **把输入收进项目**:歌曲(以及歌词文件,若来自文件)复制到 `00_source/`, `project.json` 只记录**相对项目目录**的路径。这样项目搬走后 `assemble.js` 仍能找到原声, 不会因为原文件被移动、改名或换盘而失败。内联歌词本就已写进 `storyboard.json`。 2. 用 ffprobe 读出歌曲**真实时长**(后续所有时间轴的锚点)。 3. 读取歌词:支持纯文本、内联文本、`auto`(自动找同名 `.lrc`)。 **LRC 带时间戳时**会解析出每句的真实时间点,分镜会尽量对齐,并在成片时把歌词挂到对应镜头上——这是最强的时间同步手段。 4. 让 `agnes-3.0-flash` 以「顶级 MV 导演」身份输出严格 JSON 分镜。**但它必须先交出一份完整的角色档案**: 七个维度(三视图所需的体型比例、五官特征、发型结构、服装层次、表情库、标志动作、场景气质) 全部定完之后,才开始写镜头。详见下面 **1.1**。 5. **校验 + 自动修复**:校验器会检查镜头时长是否在 4–12s、`video_prompt` 是否同时包含「摄影机运动 + 主体动作」、是否缺少必填字段、镜头数是否与时长匹配,以及**角色档案七个维度是否定全**。不合格就把**具体问题**回传给模型重写(默认最多 3 次)。档案维度缺失默认只警告并兜底;`--strict-profile` 时升级为硬失败。 6. **时间轴拟合** `fitTimeline()`:把所有镜头时长缩放到与歌曲时长**精确相等**,处理超长拆分、过短合并、余量兜底。每个镜头输出 `api_seconds`(向上取整到 4–12 的整数,供 API 使用)。 **产出** - `00_source/` —— 歌曲(+ 歌词)副本,使项目自包含 - `01_plan/storyboard.json` —— 机器可读,后续阶段都读它 - `01_plan/storyboard.md` —— 人类可读分镜表(镜头表 + 逐镜头详案 + 提示词全文) > **关键**:`plan.js` 结束后**必须用 Read 工具打开 `storyboard.md` 给用户过目**,确认故事方向、 > 人物设定、风格是否正确,再进入生图。这一步是整条流水线里最省时间的返工点。 ### 1.1 先把人物"定清楚":七维度角色档案 **这是本版最重要的方法升级。** 人物漂移的深层原因不是"模型画不准",而是**人设根本没定全**—— 规划器一边想剧情一边临时决定这个人穿什么、什么表情、在什么场景里,每个镜头各拍一次脑袋, 结果就是"同一个人在每个镜头里都像刚被重新介绍过一遍"。 正确顺序是:**先把一个人从"长什么样"一路拆到"怎么动、穿什么、适合出现在哪里",再把这个人放进分镜。** 定完之后分镜工作就退化成"把已经定好的人放进已经定好的场景"。 七个维度、对应的字段、以及它被谁消费: | # | 维度 | 字段 | 定什么 | 由谁填 | 被谁用 | |---|---|---|---|---|---| | ① | **三视图** | (由 params 自动生成) | 正面/侧面/背面全身 + 大特写 + 表情带 | 系统生成 | 身份真源 | | ② | **五官特征** | `face_shape` `eye_shape` `iris_color` `eye_spacing` `eyebrows` `nose` `lips` `jaw_chin` `skin_tone` | 脸的可复现形体结构 | 规划器写 → 视觉反读覆盖 | 每张首帧的身份块 | | ③ | **发型结构** | `hair_structure` `hair_color` | **长度 + 分缝 + 刘海 + 卷度 + 层次**(不许只写 "long hair") | 同上 | 身份块 + 身份尾 | | ④ | **服装层次** | `wardrobe_layers{inner,outer,bottoms,footwear,accessories,materials}` `garment_palette` `wardrobe` | 按穿着层次逐层拆(不许压扁成一句) | 同上 | 身份块(逐层进入提示词) | | ⑤ | **表情** | `expression_bank[4]{name,en}` + 每镜 `shot.expression` | 4 个具名表情 + 各自的英文执行描述 | **规划器独有**(设定表是中性的,视觉读不出表情) | 首帧的独立 `EXPRESSION` 块 | | ⑥ | **动作** | `signature_actions[3]` | 这个人特有的标志性动作/体态 | **规划器独有** | 镜头 `subject_action` 优先复用 | | ⑦ | **场景气质** | `scene_affinity` | 适合的空间类型、材质与光线 | **规划器独有** | 含主角镜头的选景约束 | **为什么③④要从图片反读,而⑤⑥⑦不能?** 设定表是一张**中性的、纯影棚的、单一服装的**图。它能告诉你头发怎么分层、衣服怎么穿, 但它**不包含**这个人的情绪范围、习惯动作、以及他属于什么样的世界。让视觉模型去"读"这三样, 它只会编。所以字段分两类,各归各的: ``` VISUAL_FIELDS 五官 / 发型结构 / 服装层次 / 色板 → 视觉模型从设定表真实反读(文字与画面必须一致) CREATIVE_FIELDS 表情库 / 标志动作 / 场景气质 / 气质 → 规划器拥有,原样透传(不参与反读) ``` 这条分工写死在 `lib/assets.js`(`VISUAL_FIELDS` / `CREATIVE_FIELDS`),有离线测试守着。 **表情为什么要单独走一条通道(而不是写在 `keyframe_prompt` 里)?** 因为"情绪"和"长相"是两种信息,混在一句里会互相污染。本版把表情提成独立字段: 规划器给每种表情一句英文执行描述,渲染时**单独注入一个 `EXPRESSION` 块**,并明确告诉图像模型: > 表情只改变面部肌肉;骨相、眼型与眼距、鼻、唇、下颌线、肤色、发型必须与参考图完全一致。 于是"同一个人在哭"和"同一个人在笑"不会再变成"两个长得像的人"。空镜写 `none`, 主角刻意中性写 `neutral`——两者都不会注入任何表情块。 **约束强度可控**:默认七维度缺失只给**警告并用默认值兜底**(缺失的表情库自动补 4 个默认表情, 流水线照常跑完);加 `--strict-profile` 则升级为**硬失败**,规划器必须补齐才能通过。 日常建议先用默认跑,看到警告后再针对性修正;要对交付质量有硬保证时再开 strict。 ### 1.2 地点也要"先定清楚":`scenes[]` 地点资产库 和人物一样,**地点也必须先定义成资产、再写镜头**。规划器要交出 2-4 个反复出现的地点: ```json "scenes": [ { "id": "SC1", "name": "雨夜霓虹街头", "description": "a narrow rain-soaked alley lined with shuttered storefronts…", "architecture": "wet asphalt, glazed brick walls, corrugated shutters", "lighting": "sodium street lamps overhead throwing warm pools onto the wet ground", "used_by": ["S01", "S03", "S07"] } ] ``` 然后每个镜头用 `scene_id` 引用它。产出会在 `storyboard.md` 里渲染成一张**地点资产表**, `引用镜头` 一列如果显示"无镜头引用",说明这个场景白定义了。 校验器会报三类问题:`scene_id` 引用了不存在的场景(**硬失败**)、场景字段写得太粗、 以及场景没人引用。完整机制见 **2.4**。 ### 1.3 三条分镜铁律(都是为了绕开模型的短板) | 铁律 | 问题 | 做法 | 校验 | |---|---|---|---| | **动作安全区** | 多人肢体交互(拥抱/打斗/递物/牵手)是**穿模与肢体融合的重灾区**,模型会把两条手臂融在一起 | 改用**景别切换 + 反应镜头**:特写手指停住、特写对方表情、特写两只手之间那段没碰到的距离。真要接触就压在特写/中近景里完成,别用远景交代全身交互 | 多人同框 + 动作含交互词 → 自动警告并给出替代建议 | | **情绪落点用稳镜头** | 运镜越花,越看不清脸;而全片最需要看清脸的就是那句关键歌词 | 副歌第一句 / Bridge 最高音配**固定机位或极缓推移**(`motion_intensity = 1`);环境镜头、转场、鼓点密集处才放开到 3 | 写入规划约束(软性创作建议) | | **地点要成资产** | 同一个地点在多个镜头里各自生成 → 巷子宽窄、灯位、积水颜色都会漂 | 见 1.2 / 2.4 | `scene_id` 引用有效性 | 另外 `shot.transient_state` 与 `shot.speed` 也是本版新增:前者是"天气"专用通道(淋湿的头发、 敞开的衣领),后者控制整段拍摄速度(`normal / slow-motion / fast-motion`)。 两者都进首帧的 `SHOT-LOCAL STATE` 块,**绝不混进身份描述**。 --- ## 阶段 2:角色素材 + 生图 `images.js` ```bash node "<skill-dir>/scripts/images.js" --concurrency 3 \ --sheet-candidates 2 --identity-min 70 --identity-retries 2 --keys "sk-aaa,sk-bbb" ``` > **`--project` 是可选的。** 省略时自动选取当前会话 `out/` 下**唯一**的项目; > 若有多个项目,脚本会**列出候选并要求你显式指定**,而不是猜一个——静默选错片子比报错更贵。 > 阶段 2/3/4 与 `verify.js` 都是这个规则。 ### 2.1 角色资产:三步走,每一步都依赖上一步 | 顺序 | 文件 | 作用 | |---|---|---| | 1 | `02_images/ref_charsheet.png` | **角色资产设定表** —— 全片人物身份的唯一真源 | | 2 | `02_images/character_lock.json` | **结构化身份参数 + 创意档案** —— 视觉反读的五官/发型/服装层次 + 规划器的表情库/动作/场景气质 | | 3 | `02_images/ref_face.png`、`ref_body_<角度>.png` | 面部特写 + 各角度白底全身参考图(均由**面部特写**派生,见铁律一) | | 4 | `02_images/ref_style.png` | 风格基调板(无人物),锁定色彩/光线/质感 | | 5 | `02_images/ref_scene_<id>.png` | **地点锚点**:每个反复出现的地点一张**无人空镜**,锁定空间/材质/光位/色调(见 2.4) | | 6 | `02_images/shot_S01.png` … | 逐镜头首帧(含主角的会过身份核验,并单独注入表情块) | **第 1 步:为什么是"一张设定表"而不是"定妆照"** 设定表 = **一次生成**里按上下两带排布: ``` ┌──────────────────────────────────────────────────┐ │ 上带 ~62% │ │ │ ┌──────────────┐ │ 正面 / 侧面 / 背面 │ │ │ 大胸像特写 │ │ 三个全身站立视图 │ │ └──────────────┘ │ │ ├──────────────────────────────────────────────────┤ │ 下带 ~30% 微笑 │ 害羞 │ 委屈 │ 开心 │ │ 四个表情头像(同一张脸,同框同构图) │ └──────────────────────────────────────────────────┘
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る