プラグインインストール: セットアップや更新コマンドの前に、このスキルが HyperFrames プラグイン内にある場合は プラグイン実行ルール に従ってください。スタンドアロンインストールの場合は、以下の更新手順を維持します。
最初に、このスキルを最新に保つ — ユーザーに確認してから実行:
npx hyperframes skills update music-to-video。すべてが最新であれば高速で何もしません。そうでなければ、このスキルとそれが依存するコアドメインスキルを、それらに依存する前に更新します。
music-to-video — 単一の音楽ベース、ビート同期動画ワークフロー
このスキルを使用して、音楽トラックをビート同期の HyperFrames 動画に変換します。トラックを一度解析し、フレームをレイアウトし、フレームごとの計画を埋め、各フレームをコンポジションとして構築します。入力は音楽トラックと、オプションでユーザー提供の画像または動画です — ナレーションやウェブサイトキャプチャはありません。タイポグラフィとテンプレートが基本となります(完全な動画はゼロアセットで作成可能)。ユーザーが提供したメディアは、同じビートグリッド上にカットインされます。
あなたはオーケストレーターです。videos/<project>/ で作業します。手順を順番に実行し、各ゲートを通過してから次に進んでください。2つのステップでユーザーの関与が必要です: ステップ 3(計画承認)とステップ 6(レンダリング承認) — これらは ../hyperframes/references/brief-contract.md(ステップ 0 の前に読んでください)に基づくチェックポイントゲートです: 自律モードでは、サマリーをヘッズアップとして投稿し、待たずに進めてください。自分で各ステップを実行します。ただしステップ 4 では、フレームごとに1つのサブエージェントをディスパッチします。デザインとモーションのルールはこのファイルには含めず、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。
すべてを形作る2つのアイデア
- 単一のアナライザー、そしてそれを信頼する。
analyze-beatgrid.pyが唯一のビートアナライザーです — 他のツールや耳でビートを再測定しないでください。そのエネルギー/密度/ロール/オンセット/無音は常に信頼できます。そのbpmとbeats_secは、音楽が本当にリズミカルな場合にのみ信頼できます。落ち着いた音楽の場合、グリッドはトラッカーが課したメトロノームに過ぎないので、代わりにフレーズとエネルギーでペースを決め、それに合わせてハードカットしないでください。どちらのケースに該当するかの判断は、各フレームのpacing(ステップ 2)で行います。 - 1フレーム = 1ファイル。グループは内部に存在する。 ステップ 2 でトラックをフレームにカットし、各フレームは1つのコンポジションファイル
compositions/frames/NN-<frame_id>.htmlになり、1つの frame-worker によって構築されます。フレームはグループ(各テンプレートまたはモーションプリミティブの組み合わせ)に細分化できます。追加の密度はグループの_内部_に配置されるため、フレーム数はビートではなく、異なる処理の数を追跡します — 速いトラックでもサブエージェントの数が爆発的に増えることはありません。
ステップ 0: セットアップ、BGM、および入力
目標: 音楽ソースを確立し、HyperFrames プロジェクトを作成し、ユーザー提供のメディアを記録します。
ブリーフはインテントレイヤーから始まります。 開始ルール(順序): (1) BRIEF.md が存在する → それを読み、それが答えることは何も質問しない — その flow/storyboard がモードを導き出します(ブリーフ契約 § 1)。(2) BRIEF.md はないがプロジェクトが存在する → ディスク上のものから再開。再質問は絶対にしない。(3) ここに直接届いた新規作成リクエスト → /hyperframes を読み、そのインテントレイヤー(references/intent-interview.md)を実行する: このルートの必須事項(音楽ソース、宛先 → アスペクト — ../hyperframes/references/routes/music-to-video.md)を確認し、何が延期されるかを通知する — ブランドとジャンルは設計上ステップ 3 で選択されます。init 直後に BRIEF.md を書き込む(決して前ではない — init は空でないディレクトリを拒否します)。選好に基づく回答(brief-format.md)を記録します。編集リクエストはこれらすべてをスキップします。
音楽が背骨です — 何よりも先に1つのトラックを確立します。このスキルは高速で高エネルギーのBGMに調整されています: 強力なビートグリッドがカットを駆動します(落ち着いたトラックでも動作しますが、ビートではなくフレーズでペースを決めます)。ユーザーがオーディオ(音楽ファイル、または音声を抽出するための動画)を提供した場合は、それを使用します。それ以外の場合は、リクエストからムードを選択し、/media-use(references/bgm.md)を通じてトラックを生成します。最初の認証済みプロバイダーアクションの前に、npx hyperframes auth status を実行し、その出力を逐語的に中継します。サインアウトしている場合は、1つのブランチを適用します:
- 協調モード: サインイン、またはローカルプロバイダーでオフラインで続行する明示的な選択を待ちます。
- 自律モード: ステータスを通知し、利用可能なローカルプロバイダーを通じて続行します。
必要な音楽機能を満たせるオフラインプロバイダーがない場合は、ブロッカーを表面化させます。リポジトリごとの .env にキーを書き込まないでください。認証の所有権とオフラインフォールバックは、/media-use references/setup-providers.md § プロバイダーにあります。結果のトラックは assets/bgm.mp3 に配置されます。提供された画像または動画をステージングして、フレームがビートグリッド上で使用できるようにします。それ以外の場合は、タイポグラフィが動画を支えます。
歌詞動画: ボーカルに同期された歌詞の場合、/media-use を通じてトラックを文字起こしするか、ユーザーに歌詞テキストを尋ねて、ビートグリッド上に行を配置して単語/行のタイミングを取得します。
hyperframes.json がない場合にのみ初期化します。ブリーフから <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 が存在すること。アスペクト / 長さ / fps および(もしあれば)アセットインベントリが記録されていること。
ステップ 1: 音楽を解析する
目標: 動画全体が構築される、唯一の標準的なタイミング分析を生成します。
analyze-beatgrid.py が唯一のビートアナライザーです — 他のツールや耳でビートを再測定しないでください。トラックを1回読み取り、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、および1行の 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(ユーザーがアセットを提供した場合のみ)を読んでください。同じファイルをその場で編集し、2つのことを行います:
- ブランドを選択する。
../hyperframes-creative/frame-presets/から1つのプリセットを選びます。../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 を読んでください。フレームごとに1つの frame-worker を、可能な限り並列で(そうでなければ波状に)ディスパッチします。各ワーカーは正確に1つのフレームと以下のコンテキストを取得します:
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カットでゲートし、1つのシークセーフなフレームファイルを書き込みます。ワーカーは決して hyperframes CLI を実行しません — これらのコマンドは組み立てられたプロジェクトに対して動作しますが、それはまだ存在しないため、間違ったファイルを報告することになります。ワーカーは契約に従って書き込んで停止するだけです。組み立て後(ステップ 6)に確認します。各ワーカーが戻ってきたら、そのファイルがディスクに存在することを確認できます。
ゲート: すべてのフレームの compositions/frames/NN-*.html がディスク上に存在すること。
ステップ 5: 組み立て
目標: 構築されたフレーム + BGM を再生可能な 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 は構造的な lint とヘッドレスブラウザのランタイム、レイアウト、モーションの一貫性を実行します:
cd "$PROJECT_DIR" && npx hyperframes check
すべてのチェックが成功したら、ユーザーに承認を求めます(自律モードではこれはヘッズアップゲートです)。承認されたら、最終動画をレンダリングします:
cd "$PROJECT_DIR" && npx hyperframes render --output renders/video.mp4
ゲート: check がエラーなしで合格すること。renders/video.mp4 が存在し、再生可能であること。