1实现原理 · 为什么它能做到
这是端到端 7 步带 Gate 的 workflow 技能:Step0 建项目(hyperframes.json+assets/bgm.mp3)→ Step1 音乐分析(audiomap.json)→ Step2 帧骨架(STORYBOARD.md)→ Step3 用户门禁的计划填充 → Step4 每帧一个 frame-worker 子代理并行构建 → Step5 确定性组装 index.html → Step6 用户门禁的 check+render。
Workflow: Step 0 setup → `hyperframes.json` + `assets/bgm.mp3`; Step 1 analyze → `audiomap.json`; Step 2 skeleton → `STORYBOARD.md` (frames, groups `TBD`); Step 3 plan → complete `STORYBOARD.md` + `frame.md`; Step 4 build → `compositions/frames/NN-*.html`; Step 5 assemble → `index.html`; Step 6 render → `renders/video.mp4`.
节拍分析由单一权威脚本落地:analyze-beatgrid.py(Python:librosa beat tracker + 16 分音 bar grid + 鼓组 band-split 分类 + riser/glitch/hard-stop 事件 + 能量叙事),写确定性 audiomap.json;SKILL 禁止再用其它工具/耳朵重测节拍。
`analyze-beatgrid.py` is the **only** beat analyzer — never re-measure beats with another tool or by ear. Its energy / density / rolls / onsets / silences are always reliable.
脚本对不可靠字段诚实:bpm/beats_sec 仅在音乐真正有节奏时可靠——平静音乐上网格是 tracker 强加的节拍器,每帧的 pacing(beat_cut/phrase_flow)在 Step 2 由 orchestrator 裁决。
Its `bpm` and `beats_sec` are reliable **only when the music is genuinely rhythmic**; on calm music the grid is a metronome the tracker imposed, so pace by phrases and energy instead and never hard-cut to it.
人力分配模型:orchestrator(本技能)只做计划与装配,每帧交给一个 frame-worker 子代理按固定上下文(PROJECT_DIR/frame_id/Storyboard 块/audiomap/frame.md/素材路径/契约)构建单个 composition 文件;frame 数量跟『不同处理』而非拍数(组内加密度),避免快速音乐撑爆子代理数。
Extra density goes _inside_ a group, so **frame count tracks distinct treatments, not beats** — a fast track does not blow up the number of sub-agents.
确定性装配由脚本保证:assemble-index.mjs 无子代理无判断,按 STORYBOARD 的累计 data-start 挂每帧、BGM 上 track 11、帧间硬切(无 transition injector——帧已无隙铺满轨道);validate-plan.mjs 在 Step 3 校验计划(时长不匹配/帧未铺满/缺 src 为 hard error)。
`assemble-index.mjs` is deterministic — no subagent, no judgment. It references each frame file at its cumulative `data-start`, mounts `assets/bgm.mp3` on track 11, and hard-cuts frame → frame (frames tile the track with no gaps, so there is **no transition injector**).
素材/BGM 来源链清晰:用户给音频/视频 → 提取;没有 → 走 /media-use 的 mood→track 生成(provider auth 属 media-use,SKILL 只跑 `npx hyperframes auth status` 中继输出并声明 'Never write keys into a per-repo .env');离线本地 provider 兜底。
If signed out, apply one branch: - **Collaborative:** wait for sign-in or an explicit choice to continue offline with the local provider. - **Autonomous:** state the status and continue through the available local provider.
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| package | Python3 + librosa/numpy/soundfile(analyze-beatgrid.py;缺失时 pip install) |
| cli | ffmpeg/ffprobe(analyze-beatgrid.py 解码) |
| cli | hyperframes CLI(init/update/auth status/check/render;render 带 --skill=music-to-video) |
| network | (间接)pip/npm 官方注册表首次拉包;BGM 生成走 /media-use provider(HeyGen/Lyria 等,auth 属 media-use) |
| network | 产物运行期 CDN(模板引用 jsdelivr gsap/three;作品级依赖) |
4风险提醒 风险提醒:黄色 · 留意使用
- 依赖 Python 生态与 CLI 链:librosa/numpy/soundfile、ffmpeg、hyperframes CLI 缺一即卡在某步 — SKILL 指引 pip install 兜底,但离线/受限环境需预装;版本不匹配会改变 audiomap 数值。
- autonomous 模式把两个用户门禁降级为 heads-up,交付节奏由 orchestrator 自判 — 计划/渲染门禁在 collaborative 模式强制;autonomous 需宿主信任 agent 判断。
- auth status 中继 + 委托 media-use 生成会接触账户状态/云端生成端点 — 本技能不持 key;但整链跑通时 HeyGen/Lyria 等凭证与用量面被激活,归 media-use(orange)承担。
- 帧 worker 并行度 = 帧数(可到几十),编排成本与失败重派需 orchestrator 管理 — frame count tracks treatments 缓解(组内加密度),但复杂曲目仍会触发多子代理波次。
5第二遍独立确认
- [ok] 『analyze-beatgrid.py 是唯一分析器』 — SKILL.md Step 1/Two ideas 两处声明 + 目录实测无其它分析脚本;audio 相关生成/转写均指向 media-use。
- [ok] 帧数与子代理数解耦声称 — SKILL.md 'frame count tracks distinct treatments, not beats' + frame-worker.md 'One frame = one file; groups live inside' 复核一致。
- [ok] worker 不跑 CLI 的纪律 — SKILL.md Step 4 'The worker never runs the `hyperframes` CLI…' + frame-worker.md 'Writing the file is your terminal action; the orchestrator runs lint/check' 双重复核。
- [discrepancy] auth status 是否触碰凭证 — 首轮注记『无凭证面』需细化:Step 0 确实运行 `npx hyperframes auth status` 并中继输出(登录/用量状态,账户级而非明文 token),且 BGM 生成委托 media-use 时其凭证面在 media-use。已在 credential_reads/reason 如实表述并维持 yellow。
- [ok] 渲染门禁与时长一致性判据 — Gate 文本 'the user approved … `renders/video.mp4` exists with audio, duration == audiomap.audio.duration_sec' 与 assemble 的确定性设计自洽。
6结论
7806505645ff0114…b8328f9573