当用户提供音乐曲目(音频文件或需要提取音频的视频)并希望生成与节拍同步的 HyperFrames 视频时使用,风格从平静到强烈均可。音乐驱动一切:一个分析器一次性读取音乐,编排器布局帧并填充每帧计划,一个子代理构建每帧。排版和模板是基础——完整视频无需任何素材——但用户提供的任何图片或视频都会在同一节拍网格上(节拍剪辑/肯·伯恩斯效果)切入帧中。类型(歌词视频、幻灯片、动态宣传片)由每帧的选择决定;流程从不分支。
music-to-video — 基于音乐、节拍同步的视频工作流
使用此技能将音乐曲目转化为节拍同步的 HyperFrames 视频。你一次性分析曲目,布局帧,填充每帧计划,并将每帧构建为一个合成。输入是音乐曲目加上可选的用户图片或视频——没有旁白,也没有网站捕获。排版和模板是基础(完整视频无需任何素材);用户提供的任何媒体都会在同一节拍网格上切入。
你是编排器。在 videos/<project>/ 中工作。按顺序执行步骤,并在继续之前通过每个关卡。两个步骤需要用户参与:步骤 3(计划批准)和步骤 6(渲染批准)。除步骤 4 外,所有步骤都由你自己完成,在步骤 4 中,你为每帧分派一个子代理。设计规则和运动规则不在此文件中——它们位于 references/ 和 frame-worker 子代理中。
SKILL_DIR = 此技能目录。PROJECT_DIR = videos/<project-name>/。
工作流:步骤 0 设置 → hyperframes.json + assets/bgm.mp3;步骤 1 分析 → audiomap.json;步骤 2 骨架 → STORYBOARD.md(帧,组为 TBD);步骤 3 计划 → 完整的 STORYBOARD.md + frame.md;步骤 4 构建 → compositions/frames/NN-*.html;步骤 5 组装 → index.html;步骤 6 渲染 → renders/video.mp4。
两个核心概念
- 一个分析器,并且你信任它。
analyze-beatgrid.py是唯一的节拍分析器——绝不用其他工具或耳朵重新测量节拍。它的能量/密度/滚奏/起始点/静音始终可靠。它的bpm和beats_sec仅在音乐真正有节奏时才可靠;对于平静的音乐,网格是跟踪器强加的节拍器,因此应根据乐句和能量来安排节奏,绝不要硬切到网格。判断属于哪种情况是每帧pacing(步骤 2)的任务。 - 一帧 = 一个文件;组在帧内。 步骤 2 将曲目切割成帧,每帧成为一个合成文件
compositions/frames/NN-<frame_id>.html,由一个帧工作者构建。一帧可以细分为组(每个组是一个模板或运动原语组合)。额外的密度放在组_内部_,因此帧数跟踪不同的处理方式,而不是节拍——快速曲目不会增加子代理的数量。
步骤 0:设置、背景音乐和输入
目标:确定音乐源,创建 HyperFrames 项目,并记录用户提供的任何媒体。
音乐是核心——在开始其他操作之前先确定一个曲目。此技能针对快速、高能量的背景音乐进行了优化:强大的节拍网格驱动剪辑(平静曲目也可用,但按乐句而非节拍安排节奏)。如果用户提供了音频——音乐文件或需要提取音频的视频——则使用它。如果没有,则生成一个:根据用户的描述选择情绪(例如“动感的合成波”、“陷阱节拍”、“欢快的企业风格”),并通过 /hyperframes-media(references/bgm.md——有凭据时使用 HeyGen 检索,否则使用本地 Lyria/MusicGen;ElevenLabs 或其他生成器也可用)生成曲目。在生成之前,运行 npx hyperframes auth status 并逐字输出其内容(不要改写或重述)——它显示背景音乐来自 HeyGen 还是本地 MusicGen,如果未登录,则显示如何登录。如果未登录,则停止并等待用户选择——登录,或离线继续使用本地 MusicGen——然后再生成曲目;不要将密钥写入每个仓库的 .env 文件中。(在自主模式下,记录状态并离线继续。)参见 /hyperframes-media → Preflight 获取规范指导。无论哪种方式,曲目都放在 assets/bgm.mp3。暂存用户提供的任何图片或视频,以便帧可以在节拍网格中编织它们;否则排版承载整个视频。
仅在 hyperframes.json 缺失时初始化。根据简要说明以 kebab-case 命名 <project>,例如 midnight-drive-loop——绝不要使用时间戳。init 检查已安装的技能是否与 GitHub 上的最新版本一致,并更新全局集合(如果有任何技能过时)。
npx hyperframes init "videos/<project>" --non-interactive --example=blank
mkdir -p "$PROJECT_DIR/assets" "$PROJECT_DIR/renders"
cp "<user-music>" "$PROJECT_DIR/assets/bgm.mp3" # 如果需要,先从视频中提取
# 仅当用户提供了图片/视频时:
node <SKILL_DIR>/scripts/stage-assets.mjs --from <dir> --hyperframes "$PROJECT_DIR" --into public
品牌(字体+调色板)在步骤 3 选择,而不是这里。不要预先选择类型或曲目类型——资产只是可选成分,类型从每帧的选择中产生。
关卡: hyperframes.json + assets/bgm.mp3 存在;记录宽高比/时长/帧率以及(如果有)资产清单。
步骤 1:分析音乐
目标:生成整个视频所依赖的唯一规范时间分析。
analyze-beatgrid.py 是唯一的节拍分析器——绝不用其他工具或耳朵重新测量节拍。它一次性读取曲目并写入 audiomap.json:能量阶段(级别/密度/感觉)、起始点 + onset_rate、滚奏、静音、hard_stops、key_moments、乐句、节奏/网格以及 audio.duration_sec。它是确定性的——同一个文件总是给出相同的映射。大多数字段在任何音乐上都可靠;bpm 和 beats_sec 仅在音乐真正有节奏时才可靠,判断这一点是你在步骤 2 做出的决定。
先决条件:Python 3 可用 librosa、numpy 和 soundfile。如果导入失败,在运行分析器之前将它们安装到活动的 Python 环境中:
python3 -m pip install librosa numpy soundfile
python3 <SKILL_DIR>/scripts/analyze-beatgrid.py "$PROJECT_DIR/assets/bgm.mp3" \
-o "$PROJECT_DIR/audiomap.json" --print
关卡: audiomap.json 存在;已知 audio.duration_sec。
步骤 2:帧骨架(仅结构)
目标:读取音乐并布局帧——STORYBOARD.md 的骨架。
阅读 references/frame-skeleton.md。你自己将 audiomap.json 转化为 STORYBOARD.md 的骨架——没有中间 JSON。在真实的音乐变化处(hard_stops、SURGE/DROP key_moments、滚奏边缘、无起始点的段落、大的能量跳跃)将曲目切割成帧,将每个边界对齐到 audiomap 锚点。为每帧设置 span_sec、pacing(来自步骤 1 信任判断的结论——当网格真实时为 beat_cut,当网格是强加于平静音乐的节拍器时为 phrase_flow)、mood 和一行 feel(步骤 3 将模板与之匹配的纯音乐情况)。在此仅进行分类和布局:将每帧的 ### Groups 保留为 TBD (Step 3),并将 frontmatter style 留空——没有模板、文案、颜色或字体。预计约 1–6 帧。
关卡: 帧覆盖整个曲目(第一帧从 0 开始,最后一帧在 duration_s 结束);每帧包含 span_sec + pacing + mood + feel;每个 ### Groups 都是 TBD;没有任何内容。
步骤 3:填充计划(用户关卡)
目标:将骨架转化为已批准、完整的 STORYBOARD.md。
阅读 references/planning.md、storyboard-format.md、template-catalog.md、motion-primitive-catalog.md 和 montage.md(仅当用户提供了资产时)。在原地编辑同一个文件,做两件事:
- 选择品牌。 从
../hyperframes-creative/frame-presets/中选择一个预设,使用../hyperframes-creative/references/design-spec.md中的表格(匹配曲目的情绪;只有其字体和颜色重要——模板拥有构图)。将其未经修改复制到frame.md中,并从其中填充 frontmatterstyle(字体 + 最多 4–6 色板调色板)。 - 填充每帧。 决定其组,并为每个组指定处理方式:从目录中匹配的模板(带有绑定参数和真实的 audiomap 锚点)、从原语目录中自由组合、或遵循
pacing的资产处理。编写文案。你拥有 WHAT(模板/原语 + 内容 + 锚点);帧工作者拥有 HOW——绝不要将毫秒级补间写入故事板。
node <SKILL_DIR>/scripts/validate-plan.mjs --storyboard "$PROJECT_DIR/STORYBOARD.md" \
--audiomap "$PROJECT_DIR/audiomap.json" --templates <SKILL_DIR>/references/templates
修复每个 ✗(硬错误:时长不匹配、帧未覆盖曲目、缺少 src);警告尽力而为。然后向用户显示逐帧摘要,并迭代直到他们批准。
关卡: frame.md 是逐字复制的预设;validate-plan.mjs 退出码为 0;用户批准了计划。
步骤 4:根据计划构建帧
目标:将每帧构建为独立的合成文件。
创建 compositions/frames/。阅读 sub-agents/frame-worker.md 和 ../hyperframes-core/references/subagent-dispatch.md。为每帧分派一个帧工作者,尽可能并行(否则分批)。每个工作者只获得一帧和以下上下文:
PROJECT_DIR: <绝对路径>
frame_id: <NN-frame_id> # = 帧文件名,例如 02-f2;合成 ID
你的块:PROJECT_DIR/STORYBOARD.md 中的 `## Frame N — <frame_id>` 块
audiomap: PROJECT_DIR/audiomap.json
frame.md: PROJECT_DIR/frame.md
材料:对于每个组,<SKILL_DIR>/references/templates/<id>/index.html(模板)和
<SKILL_DIR>/references/motion-primitives/<id>/(自由组合);暂存的 assets/(资产组)
合约:../hyperframes-core/references/sub-compositions.md + determinism-rules.md
画布:<w>×<h> 节奏:<beat_cut|phrase_flow>
写入:PROJECT_DIR/compositions/frames/<frame_id>.html
工作者分叉引用的材料,将每个锚点转换为帧本地秒数(local_t = track_t − span_sec[0]),用 0ms 剪辑门控其组,并写入一个可寻帧的帧文件。工作者从不运行 hyperframes CLI——这些命令操作于已组装的项目,该项目尚不存在,因此它们会报告错误的文件。工作者只写入合约并停止;你在组装后验证(步骤 6)。当每个工作者返回时,你可以确认其文件已写入磁盘。
关卡: 每帧的 compositions/frames/NN-*.html 都在磁盘上。
步骤 5:组装
目标:将构建的帧 + 背景音乐连接到可播放的 index.html 中。
assemble-index.mjs 是确定性的——没有子代理,没有判断。它引用每个帧文件在其累积的 data-start 处,将 assets/bgm.mp3 挂载到轨道 11,并硬切帧到帧(帧覆盖曲目且无间隙,因此没有过渡注入器)。
node <SKILL_DIR>/scripts/assemble-index.mjs --storyboard "$PROJECT_DIR/STORYBOARD.md" \
--hyperframes "$PROJECT_DIR" --audiomap "$PROJECT_DIR/audiomap.json"
修复它报告的任何 ✗——缺失或空白的帧文件意味着该工作者写入了部分文件;重新分派它(步骤 4)并重新组装。
关卡: index.html 存在;总时长 == audiomap.audio.duration_sec。
步骤 6:验证和渲染
目标:验证组装的视频,获得用户批准,并渲染最终的 MP4。
在已组装的项目上运行 CLI——这是正确的单元(每帧工作者无法运行它)。lint 检查结构,validate 运行无头 Chrome(捕获 JS 错误和缺失资产),inspect 快照帧。
( cd "$PROJECT_DIR" && npx hyperframes lint . && npx hyperframes validate . && npx hyperframes inspect . )
在 t=0、每帧开始、最强的 DROP/SURGE、每个 hard_stops[].t 以及最后一帧处检查。如果失败,自己进行最便宜的安全修复:编辑有问题的 compositions/frames/NN-*.html。绝不要更改时长或音频时序来隐藏同步问题。一旦关卡通过,暂停等待用户审查,然后仅在批准后渲染:
( cd "$PROJECT_DIR" && npx hyperframes render . --skill=music-to-video -q draft -o renders/video.mp4 --fps 30 )
关卡: lint/validate/inspect 通过;用户批准;renders/video.mp4 存在,包含音频,时长 == audiomap.audio.duration_sec。最终回复说明 MP4 路径和时长。
恢复表
| 你已有 | 从何处继续 |
|---|---|
仅有 assets/bgm.mp3 |
步骤 1 |
audiomap.json |
步骤 2 |
STORYBOARD.md(骨架) |
步骤 3 |
STORYBOARD.md(完整) |
步骤 4 |
| 所有帧文件 | 步骤 5 |
index.html |
步骤 6 |
快速参考
格式: 默认横向 1920x1080;纵向 1080x1920;方形 1080x1080。在故事板 frontmatter 中设置一次画布(canvas: { w, h, fps })。
脚本位于 scripts/ 下:analyze-beatgrid.py(唯一分析器)、validate-plan.mjs(计划检查)、assemble-index.mjs(索引组装)、stage-assets.mjs(暂存用户媒体)、lib/storyboard.mjs(供应商解析器)。其他一切都是 hyperframes CLI。
| 阅读 | 何时 |
|---|---|
references/frame-skeleton.md |
步骤 2:读取音乐,布局帧,设置节奏 |
references/planning.md · storyboard-format.md |
步骤 3:选择品牌,填充每帧,编写计划 |
references/template-catalog.md |
步骤 3:为每个组选择模板 |
references/motion-primitive-catalog.md |
步骤 3/4:自由组合的 L0 配方 |
references/montage.md |
步骤 3/4:资产处理(节拍剪辑/肯·伯恩斯) |
sub-agents/frame-worker.md |
步骤 4:分派并构建一帧 |
../hyperframes-core/references/subagent-dispatch.md |
步骤 4:安全分派子代理 |
../hyperframes-creative/references/design-spec.md |
步骤 3:选择预设(品牌) |
目录布局
music-to-video/
SKILL.md
references/ frame-skeleton.md · planning.md · storyboard-format.md
template-catalog.md · motion-primitive-catalog.md · montage.md
templates/<id>/ { index.html (+ assets/ · program.json) } ← L1 目录实现
motion-primitives/<id>/ { index.html } (+ ../assets/gsap.min.js 由配方共享) ← L0 目录实现
scripts/ analyze-beatgrid.py · assemble-index.mjs · validate-plan.mjs · stage-assets.mjs · lib/storyboard.mjs
sub-agents/ frame-worker.md ← 唯一的子代理(每帧一个)






