當使用者有一段音樂(音訊檔案或可從中提取音訊的影片),且希望製作一部與節拍同步的 HyperFrames 影片時使用,風格從平靜到強烈皆可。音樂驅動一切:一個分析器讀取一次,編排器規劃影格並填入每個影格的計畫,再由一個子代理構建每個影格。排版與模板是基本盤——一部完整的影片不需要任何素材——但使用者提供的任何圖片或影片都會在同一個節拍網格上(節拍剪輯 / 肯·伯恩斯效果)被剪入影格中。類型(歌詞影片、幻燈片、動感宣傳片)由每個影格的選擇決定;流程不會根據類型分支。
music-to-video — 單一音樂驅動、節拍同步的影片工作流程
使用此技能將一段音樂曲目轉換為節拍同步的 HyperFrames 影片。您分析曲目一次,規劃影格,填入每個影格的計畫,並將每個影格構建成一個合成。輸入是一段音樂曲目加上使用者可選的圖片或影片——沒有旁白,也沒有網站擷取。排版與模板是基本盤(一部完整的影片不需要任何素材);使用者提供的任何媒體都會在同一個節拍網格上被剪入。
您是編排器。在 videos/<project>/ 中工作。依序執行步驟,並在繼續前通過每個關卡。有兩個步驟需要使用者:步驟 3(計畫批准)和步驟 6(渲染批准)。除了步驟 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 專案,並記錄使用者提供的任何媒體。
音樂是主幹——在進行任何其他操作之前先確定一首曲目。此技能針對快速、高能量的背景音樂進行了調整:強烈的節拍網格驅動剪輯(平靜的曲目也可以,但應以樂句而非節拍為節奏)。如果使用者提供了音訊——音樂檔案或可從中提取音訊的影片——請使用它。如果沒有,則生成一個:從使用者的描述中選擇情緒(例如「強勁的合成波」、「陷阱節拍」、「 upbeat 企業風格」),並透過 /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/references/design-spec.md中的表格,從../hyperframes-creative/frame-presets/中選擇一個預設(匹配曲目的情緒;只有其字型和顏色重要——模板擁有合成權)。將其未經修改複製到frame.md中,並從中填入 frontmatterstyle(字型 + 一個 ≤4–6 色調色盤)。 - 填寫每個影格。 決定其群組,並為每個群組指定處理方式:從目錄中匹配的模板(帶有綁定參數和真實的 audiomap 錨點)、從基元目錄中自由組合,或遵循
pacing的素材處理方式。撰寫文案。您擁有 WHAT(模板/基元 + 內容 + 錨點);frame-worker 擁有 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。為每個影格分派一個 frame-worker,盡可能並行(否則分批進行)。每個 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: <w>×<h> Pacing: <beat_cut|phrase_flow>
Write to: PROJECT_DIR/compositions/frames/<frame_id>.html
Worker 會複製引用的材料,將每個錨點轉換為影格本地秒數(local_t = track_t − span_sec[0]),以 0 毫秒剪輯來控制其群組,並寫入一個可安全搜尋的影格檔案。Worker 絕不執行 hyperframes CLI——這些命令作用於已組裝的專案,而該專案尚不存在,因此它們會報告錯誤的檔案。Worker 只寫入合約並停止;您在組裝後(步驟 6)進行驗證。當每個 worker 返回時,您可以確認其檔案已存在於磁碟上。
關卡: 每個影格都有其 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"
修復其報告的任何 ✗——缺少或空白的影格檔案表示該 worker 寫入了部分檔案;重新分派它(步驟 4)並重新組裝。
關卡: index.html 存在;總持續時間 == audiomap.audio.duration_sec。
步驟 6:驗證與渲染
目標:驗證組裝好的影片,獲得使用者批准,並渲染最終的 MP4。
在已組裝的專案上執行 CLI——這是正確的單元(每個影格的 worker 無法執行它)。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:讀取音樂,規劃影格,設定 pacing |
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 ← 唯一的子代理(每個影格一個)






