插件安装: 在运行 setup 或 freshness 命令之前,当此技能位于 HyperFrames 插件内部时,请遵循插件执行规则。独立安装则保留下面的更新说明。
首先,保持此技能最新——请与用户确认后再运行:
npx hyperframes skills update music-to-video。如果一切正常,此操作会快速完成;否则,它会刷新此技能及其依赖的核心领域技能,然后您才能依赖它们。
music-to-video — 一个基于音乐、节拍同步的视频工作流
使用此技能将音乐曲目转换为节拍同步的 HyperFrames 视频。您一次分析曲目,布局帧,填充逐帧计划,并将每一帧构建为合成。输入是一个音乐曲目加上用户提供的可选图片或视频——没有旁白,也没有网站捕获。排版和模板是基础(完整视频无需任何素材);用户提供的任何媒体都将被剪辑到同一节拍网格上。
您是编排者。在 videos/<project>/ 中工作。按顺序运行步骤,并在继续之前通过每个门控。两个步骤需要用户:步骤 3(计划审批)和 步骤 6(渲染审批)——两者都是根据 ../hyperframes/references/brief-contract.md(在步骤 0 之前阅读)的检查点门控:在自主模式下,将摘要作为提示发布并继续执行,而不是等待。除了步骤 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,由一个 frame-worker 构建。一帧可以细分为组(每个组是一个模板或一个运动原语组合)。额外的密度放在_组内部_,因此帧计数跟踪的是不同的处理方式,而不是节拍——快节奏曲目不会增加子智能体的数量。
步骤 0:设置、背景音乐和输入
目标:确定音乐来源,创建 HyperFrames 项目,并记录用户提供的任何媒体。
从意图层开始。 按顺序的开场规则:(1) BRIEF.md 存在 → 读取它,不要询问它已回答的任何问题——其 flow/storyboard 推导出模式(brief contract § 1)。(2) 不存在 BRIEF.md 但项目存在 → 从磁盘上的内容恢复;绝不重新询问。(3) 直接到达此处的全新创作请求 → 读取 /hyperframes 并运行其意图层(references/intent-interview.md):它确认此路由的必需品(音乐来源,目的地→宽高比——../hyperframes/references/routes/music-to-video.md),并宣布哪些内容被推迟——品牌和流派按设计在步骤 3 选择。在初始化后立即写入 BRIEF.md(绝不能在此之前——init 拒绝非空目录)并记录以偏好为基础的答案(brief-format.md)。编辑请求跳过所有这些。
音乐是骨干——在一切之前先确定一个曲目。此技能针对快速、高能量的背景音乐进行了优化:强大的节拍网格驱动剪辑(平静曲目也可以,但应按乐句而不是节拍来定速)。如果用户提供了音频——音乐文件或要从中提取音频的视频——请使用它。否则从请求中选择情绪并通过 /media-use 生成一个曲目(references/bgm.md)。在首次经过身份验证的提供者操作之前,运行 npx hyperframes auth status 并逐字输出其结果。如果已注销,则应用一个分支:
- 协作模式: 等待登录或明确选择使用本地提供者离线继续。
- 自主模式: 说明状态并通过可用的本地提供者继续。
如果没有离线提供者能够满足所需的音乐功能,请提出这个阻碍。切勿将密钥写入每个仓库的 .env 文件。身份验证所有权和离线回退方案位于 /media-use 的 references/setup-providers.md § Providers。生成的曲目将位于 assets/bgm.mp3。暂存提供的图片或视频,以便帧可以在节拍网格上使用它们;否则,排版将承载视频。
歌词视频: 对于与歌词同步的人声,通过 /media-use 转录曲目以获取单词/行时间,或向用户询问歌词文本并将其放置在节拍网格上。
仅当 hyperframes.json 缺失时才进行初始化。根据 brief 中 kebab-case 格式的项目名称命名 <project>,例如 midnight-drive-loop——绝不用时间戳。init 会检查已安装的技能是否与 GitHub 上的最新版本一致,并更新全局集(如果任何技能已过时)。
npx hyperframes init "videos/<project>" --non-interactive --example=blank --skill=music-to-video
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、滚奏边缘、没有起始的区域、大的能量跳跃)将曲目切割成帧,并将每个边界对齐到音频映射的锚点。为每帧设置 span_sec、pacing(来自步骤 1 信任调用的判定——beat_cut 当网格真实时,phrase_flow 当它是强加于平静音乐的节拍器时)、mood 和一行 feel(步骤 3 将模板与之匹配的普通音乐情况)。仅在此分类和布局:将每帧的 ### Groups 保留为 TBD (Step 3),并将元数据中的 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中,并从中填充元数据style(字体 + 一个 ≤4–6 色板调色板)。 - 填充每帧。 决定其组,并为每个组指定一种处理方式:从目录中匹配的模板(带有绑定参数和真实的音频映射锚点)、从原语目录中自由组合、或遵循
pacing的素材处理。在您自由组合命名外观之前,先搜索实时目录:对于用户要求的每个外观、效果、处理或过渡——如“CRT 扫描线”、“故障”、“胶片颗粒”、“闪光扫掠”——运行npx hyperframes catalog --query "<外观,用简单英语描述>" --json并阅读顶部结果。template-catalog.md和motion-primitive-catalog.md仅列出此技能自己的本地材料;搜索会排名整个托管注册表(约 400 个块和组件),并且无需安装任何东西——无需项目、无需预先add、无需账户。仅当搜索后没有找到合适的内容时,才自由组合外观。编写文案。您拥有 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);警告是尽力而为。然后将逐帧摘要作为提案在聊天中展示(../hyperframes/references/review-loop.md § 1),并根据用户的回复进行迭代,直到他们批准;对于 storyboard: yes,还要将其编写为 storyboard.html(../hyperframes-creative/references/storyboard-recipe.md § 3)供他们打开。在自主模式下,这是一个检查点门控:将摘要作为提示发布并继续执行(validate-plan.mjs 通过是一个质量门控,仍然会阻止)。
门控: frame.md 是预设的逐字副本;validate-plan.mjs 退出码为 0;用户批准了计划(自主模式:摘要已作为提示发布)。
步骤 4:根据计划构建帧
目标:将每一帧构建为自包含的合成文件。
创建 compositions/frames/。阅读 sub-agents/frame-worker.md 和 ../hyperframes/references/subagent-dispatch.md。为每一帧分派一个 frame-worker,尽可能并行(否则按波次)。每个工作器恰好获得一帧和以下上下文:
PROJECT_DIR: <绝对路径>
frame_id: <NN-frame_id> # = 帧文件名,例如 02-f2;合成 ID
Your block: PROJECT_DIR/STORYBOARD.md 中的 `## Frame N — <frame_id>` 块
audiomap: PROJECT_DIR/audiomap.json
frame.md: PROJECT_DIR/frame.md
Materials: 对于每个组,<SKILL_DIR>/references/templates/<id>/index.html(模板)和
<SKILL_DIR>/references/motion-primitives/<id>/(自由组合);暂存的 assets/(素材组)
Contracts: ../hyperframes-core/references/sub-compositions.md + determinism-rules.md
Canvas: <宽>×<高> Pacing: <beat_cut|phrase_flow>
Write to: PROJECT_DIR/compositions/frames/<frame_id>.html
工作器会派生引用的素材,将每个锚点转换为帧本地秒数(local_t = track_t − span_sec[0]),使用 0 毫秒剪辑来门控其组,并写入一个可安全跳转的帧文件。工作器绝不运行 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——那是正确的单元(逐帧工作器无法运行它)。check 运行结构检查和无头浏览器的运行时、布局、运动