mcpField
B
beat-sync-video-editing

beat-sync-video-editing

github.com/ecliptic-aiクリエイティブ・メディア1792 回インストール11 週間前に更新
リポジトリ

beat-sync-video-editing について

ビデオと音声を使い、Gemini で編集プランを作成して FFmpeg でレンダリングする、ビート同期編集向けのスキルです。プランの検証やフィルター生成も行います。

主な機能

  1. 01Gemini による編集プラン生成
  2. 02EditPlan JSON の検証
  3. 03FFmpeg フィルターの構築
  4. 04FFmpeg による動画レンダリング
  5. 05アップロード済みファイルの再利用

活用シーン

  1. 01音楽のビートに同期した編集
  2. 02動画から選んだ場面の組み合わせ
  3. 03プロンプトに応じたテンポ調整

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ecliptic-ai/skills --skill beat-sync-video-editing

インストール後、Claude Code で/beat-sync-video-editingを入力して読み込まれたか確認します。

同梱ファイルreferences/edit-plan-schema.mdreferences/ffmpeg-filters.md

詳細

ビートに合わせた動画編集

目的

ビートに合わせた動画編集を作成するための専門知識を提供します。ソース動画と音声トラックを使用し、音楽のリズムに合う動画クリップを選んで、FFmpeg で最終出力をレンダリングします。

核となる概念:EditPlan

すべての編集は EditPlan から始まります。これは、使用する動画クリップと音声内での配置場所を記述する JSON 構造です。

{
  "audio_start": "00:13",
  "audio_duration": 6.5,
  "clips": [
    { "video_start": "00:08", "duration": 2.0, "description": "Opening shot" },
    { "video_start": "00:45", "duration": 1.5, "description": "Action moment" },
    { "video_start": "01:22", "duration": 3.0, "description": "Build-up" }
  ],
  "reasoning": "Matches rising intensity with beat drops"
}

タイムスタンプ形式: audio_start と video_start には MM:SS 形式の文字列を使用します(例:1 分 15 秒の場合は "01:15")。audio_duration とクリップの duration には秒数を数値で指定します。

重要な制約:

  • audio_start は有効な MM:SS 形式で、負の値であってはなりません
  • audio_duration は正の値(秒)である必要があります
  • すべてのクリップで、有効な MM:SS 形式の video_start と正の duration(秒)が必要です
  • すべてのクリップの長さの合計は、audio_duration と一致する必要があります(許容誤差は 0.5 秒)
  • クリップの順序は意図的に設定します。時系列順とは限りません。非線形の順序にすることで、躍動感のある編集になります。

ワークフロー:ファイルから最終動画まで

ステップ 1:Gemini で EditPlan を生成する

Gemini スクリプトを実行し、動画と音声を分析してプランを作成します。

# Fresh upload (default: files kept 48h for reuse, ECLIPTIC_FILES printed on stderr):
bash ${CLAUDE_PLUGIN_ROOT}/scripts/gemini-edit-plan.sh \
  --video <video_path> \
  --audio <audio_path> \
  --prompt "<user's edit description>"

# Reuse previously uploaded files (skips upload, much faster):
bash ${CLAUDE_PLUGIN_ROOT}/scripts/gemini-edit-plan.sh \
  --video-uri <uri> --video-mime <mime> \
  --audio-uri <uri> --audio-mime <mime> \
  --prompt "<different description>"

# One-shot mode (delete files immediately after use):
bash ${CLAUDE_PLUGIN_ROOT}/scripts/gemini-edit-plan.sh \
  --video <video_path> \
  --audio <audio_path> \
  --prompt "<description>" --cleanup
  • EditPlan JSON を標準出力に、進行状況を標準エラー出力に書き込みます
  • GEMINI_API_KEY、curl、jq が必要です
  • Gemini は動画を見ながら、同時に音声を聴きます

対応形式(Interactions API で適用される形式です。ほかの形式はすべて拒否されます):

  • 動画:mp4、mov、avi、mpeg、mpg、webm、wmv、3gpp(mkv は非対応です。「トラブルシューティング」を参照)
  • 音声:mp3、wav、aac、ogg、flac、m4a、opus、aiff

ファイルのライフサイクル。 スクリプトはデフォルトでアップロード済みファイルを保持するため、後続の実行で再アップロードせずに再利用できます。Gemini の TTL は 48 時間です。期限が切れると URI は無効になり、再アップロードが必要です。各実行では、video_name、audio_name、URI、MIME タイプを含む ECLIPTIC_FILES JSON 行が標準エラー出力に出力されます。これを保存して、--video-uri/--audio-uri を使った反復処理に利用してください。また、スクリプトは新規アップロードを行った実行の最後に、正確な cleanup-gemini-files.sh コマンドを出力します。削除コマンドが明示され、コピーして貼り付けられる形式になります。ECLIPTIC_FILES の行を失った場合は、bash ${CLAUDE_PLUGIN_ROOT}/scripts/list-gemini-files.sh を実行すると、現在アップロードされているすべてのファイルの名前、URI、MIME タイプ、有効期限を一覧表示できます。デフォルトで一度限りの削除を行うには、--cleanup を指定するか、環境変数に GEMINI_CLEANUP=1 を設定します。--no-cleanup は、デフォルトと同じ動作をするエイリアスとして受け付けられます。

モデルの選択。 スクリプトのデフォルトは gemini-3.6-flash です。別のモデルを使用するには、実行前に GEMINI_MODEL をエクスポートします。

export GEMINI_MODEL=gemini-3.1-pro-preview   # stronger reasoning, slower
# or
export GEMINI_MODEL=gemini-3.5-flash-lite    # cheaper/faster for simple edits

モデル名はリクエストボディにそのまま渡されるため、動画と音声の入力、および構造化 JSON 出力に対応した Gemini モデルであれば使用できます。非推奨の gemini-2.x および gemini-1.5 モデルは使用しないでください。

調整(任意の環境変数)。 どちらもデフォルトでは未設定で、その場合は API/モデルのデフォルト値が使用されます。

export GEMINI_MEDIA_RESOLUTION=high    # low | medium | high | ultra_high
export GEMINI_THINKING_LEVEL=medium    # minimal | low | medium | high
  • GEMINI_MEDIA_RESOLUTION — モデルが各フレームで認識する視覚的な詳細度です。値を上げると、詳細な映像でのクリップ選択が向上しますが、トークンコストも高くなります。
  • GEMINI_THINKING_LEVEL — モデルが編集について推論する時間です。minimal はシンプルな編集に最も速く、低コストです。複雑なペース配分のリクエストには high が役立ちます。

API に関する注意。 スクリプトは Gemini Interactions API(POST /v1beta/interactions)を呼び出し、動画と音声を型付き入力パーツとして参照し、response_format を使って EditPlan スキーマを適用します。リクエストは store: false を指定して送信されるため、インタラクションはサーバー側に保持されません(アップロード済みファイルは別扱いです。上記のファイルのライフサイクルを参照してください)。

ステップ 2:プランを検証する
echo '<plan_json>' | bash ${CLAUDE_PLUGIN_ROOT}/scripts/validate-plan.sh
  • {"valid": true, "errors": []} または {"valid": false, "errors": [...]} を出力します
  • 終了コード 0 = 有効、1 = 無効
ステップ 3:FFmpeg フィルターを作成する
echo '<plan_json>' | bash ${CLAUDE_PLUGIN_ROOT}/scripts/build-filter.sh
  • {"videoFilter": "...", "audioFilter": "...", "fullFilter": "..."} を出力します
  • fullFilter フィールドは、FFmpeg の -filter_complex 引数に指定します
ステップ 4:FFmpeg でレンダリングする
ffmpeg -y -i "<video_path>" -i "<audio_path>" \
  -filter_complex "<fullFilter>" \
  -map "[outv]" -map "[outa]" \
  -c:v libx264 -preset fast -crf 23 \
  -c:a aac -shortest \
  "<output_path>"

FFmpeg フィルターの構成

3 つのクリップを編集する場合、fullFilter は次のようになります。

[0:v]trim=start=8.000:duration=2.000,setpts=PTS-STARTPTS[v0];
[0:v]trim=start=45.000:duration=1.500,setpts=PTS-STARTPTS[v1];
[0:v]trim=start=22.000:duration=3.000,setpts=PTS-STARTPTS[v2];
[v0][v1][v2]concat=n=3:v=1:a=0[outv];
[1:a]atrim=start=13.000:duration=6.500,asetpts=PTS-STARTPTS[outa]
  • [0:v] = 1 つ目の入力(映像)、[1:a] = 2 つ目の入力(音声)
  • trim はセグメントを切り出し、setpts=PTS-STARTPTS はタイムスタンプをリセットします
  • concat はすべての映像セグメントを順番につなぎます
  • atrim は音声部分を切り出します

FFmpeg フィルターの全リファレンスについては、${CLAUDE_SKILL_DIR}/references/ffmpeg-filters.md を参照してください。

トラブルシューティング

長さの不一致エラー:クリップの長さの合計が audio_duration と一致していません。最後のクリップの長さを調整して差を吸収するか、より厳密なプロンプトを指定して Gemini を再実行してください。

FFmpeg の標準エラー出力に「Error」が表示される:FFmpeg は標準エラー出力に進捗状況や警告を書き込みます。出力ファイルが作成されなかった場合にのみ、実際のエラーとして扱ってください。No such file、Invalid data、Conversion failed など、実際のエラーパターンを確認してください。

未対応の形式(.mkv):Interactions API は Matroska を受け付けません。まず、再エンコードせずにコンテナを変更してください:ffmpeg -i input.mkv -c copy input.mp4。

有効期限切れのファイル URI:アップロードしたファイルは 48 時間後に期限切れになります。--video-uri/--audio-uri を使った再利用の実行が、ファイルに関する Gemini エラー(ファイルが見つからない、権限が拒否されたなど)で失敗する場合、URI は古くなっています。新しいコピーをアップロードするため、ローカルパスの --video/--audio を使って再実行してください。

Gemini が適切なクリップを返さない:プロンプトを具体的にしてください。「編集を作成して」ではなく、「テンポの速い 30 秒のアクション編集にして、ビートが落ちるたびに 1~2 秒ごとにカットし、サビから始めて」のように指定してください。

追加リソース

リファレンスファイル
  • ${CLAUDE_SKILL_DIR}/references/ffmpeg-filters.md — FFmpeg の filter_complex 構文、エンコードオプション、一般的なフラグの詳細
  • ${CLAUDE_SKILL_DIR}/references/edit-plan-schema.md — EditPlan の完全な JSON スキーマ、検証ルール、エッジケース
スクリプト
  • ${CLAUDE_PLUGIN_ROOT}/scripts/gemini-edit-plan.sh — REST API 経由で Gemini にアップロードし、EditPlan を取得します(--cleanup と --video-uri/--audio-uri を使ったアップロード済みファイルの再利用に対応)
  • ${CLAUDE_PLUGIN_ROOT}/scripts/validate-plan.sh — EditPlan JSON を検証します
  • ${CLAUDE_PLUGIN_ROOT}/scripts/build-filter.sh — EditPlan を FFmpeg フィルターに変換します
  • ${CLAUDE_PLUGIN_ROOT}/scripts/list-gemini-files.sh — アップロードしたファイルの名前、URI、有効期限を一覧表示します
  • ${CLAUDE_PLUGIN_ROOT}/scripts/cleanup-gemini-files.sh — 編集の反復が完了したら、アップロードしたファイルを Gemini から削除します

コメント