Communitygithub.com

binay-py/event-recap-video

山のようなイベント写真や動画(会議、旅行、リトリート、結婚式など)から、ffmpegを使ってインパクトのあるレキャップ動画を生成します。16:9本編、9:16バージョン、約45秒のビート同期リールを作成できます。

event-recap-video とは?

このスキルは、ユーザーが自身で撮影したイベントの写真・動画から、プロフェッショナルなレキャップ動画を自動生成するための強力なツールです。780点のメディアライブラリでエンドツーエンドのテストが行われており、ffmpeg/ffprobeとPython 3.10+が必要です。Google Photosからのメディア取り込みをCDP(Chrome DevTools Protocol)経由で自動化し、EXIFデータを利用した分析、重複やブラー、ラウドネスの検出、さらにビート検出による音楽同期までをカバーします。最終出力は16:9の本編、9:16の縦長バージョン、そしてTikTok/Instagram向けのビート同期リール(約45秒)の3種類を生成可能。編集はJSONファイルで定義し、フック、スピーチ部分の自動ミューダック、複数トラックのクロスフェードなど、高度な編集機能を備えています。開発者やAIエージェントユーザーは、このスキルを使って、大量の生メディアから短時間で魅力的なハイライト動画を生成できます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/binay-py/claude-skills/tree/HEAD/skills/event-recap-video

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

イベントレキャップ動画

780点のイベントライブラリでエンドツーエンドのテスト済み。ffmpeg/ffprobe がPATHに含まれていることと、Python 3.10+ で pip install pillow pillow-heif numpy が必要です。

スクリプトはこのファイルの隣にあります。プロジェクトにコピーしてください:

  • scripts/analyze.py, build.py, reel.py, motion.py, fonts.py → プロジェクトルート
  • scripts/work/*.py → <プロジェクト>/work/
  • examples/*.json → プロジェクトルート(編集して使用)

プロジェクト構成: raw/(未加工のオリジナル), music/, work/(キャッシュ), output/, edit.json(編集全体)。 フォントはWindows/macOS/Linuxで自動的に検出されます。FONT_SERIF, FONT_SERIF_BOLD, FONT_SANS_BOLD, FONT_BLACK, FONT_EMOJI で上書き可能です。

1. メディアを入手する

  • 各エクスポート/zipを raw/ の下に独自フォルダに配置します。オリジナルは絶対に変更しないでください。
  • Google Photosには既存のライブラリ用のAPIがありません。CDP(このリポジトリの brave-cdp スキルを参照)を介して、ユーザーのログイン済みブラウザを操作します。グリッドアイテムは a[href*="/photo/"]、日付ヘッダーは [role=checkbox][aria-label^="Select all photos from"] です。
  • 日付ヘッダーは実際のマウスイベント(Input.dispatchMouseEvent)で選択し、"N selected" のテキストを確認し、Shift+D を押します。タブは前面にある必要があります(Page.bringToFront)。そうしないとグリッドがグレー表示のままになります。
  • Googleはダウンロード後に選択をクリアするため、ヘッダーの aria-checked が古くなる可能性があります。再選択する前にリロードしてください。
  • Browser.setDownloadBehavior を allowAndName で設定すると、zipがGUIDのまま拡張子なしで保存されます。Browser.downloadProgress で completed を監視します。

2. 分析と選択

  • python analyze.py → work/media.json(EXIF / 動画 creation_time からローカルタイムゾーンでの撮影時間、ブラー、明るさ、重複、ラウドネス)+ 日ごとのコンタクトシートが work/sheets/ に生成されます。
  • python work/vsheets.py → 動画あたり3フレームのストリップを生成。すべてのシートを確認してください。撮影中に回転するクリップ、ポケットショット、暗い夜のクリップはスキップします。
  • python work/loudest.py ID:seconds ... で最もラウドなウィンドウ(歌、スピーチ、歓声)を見つけます。トリミング前に1 fpsのフレームストリップで確認してください。
  • 共有/転送されたファイルには撮影日がありません(ファイルのmtimeにフォールバック)—目視で配置します。

3. 編集(視聴者が好むもの)

  • 動画を先頭に配置(クリップの約90%)。写真は強力なグループショットにのみ使用します。写真中心のカットは間延びします。
  • 冷たいオープンフック: 1.2~1.8秒のクリップを8~10個、hook_xf 0.1でほぼハードカット、その後タイトルカード。次に日付順に、各日の最初のクリップに小さな "label": "Day N · 日付" を付け、3~4秒のカット、そして "speech": true とフラグが立てられた数個の9~12秒の瞬間(音楽がその下にダックします)。
  • 音楽でフックの良し悪しが決まります。同じテンポの2トラックをチェーン("music": [a, b]、3秒クロスフェード)で接続し、ループを避けます。python work/bpm.py file.mp3 でテンポを推定します。
  • edit.json のキー: title, subtitle, closing, closing_sub, title_bg / closing_bg(+ _bg_at 動画ID用)、music / vertical_music, music_volume, duck_volume, ambient_volume, photo_seconds, hook_xf, closing_seconds, horizontal_hook, horizontal, vertical_hook, vertical。セグメント: {"id", "at" (0–1 中央) | "start", "dur", "speech", "label", "xf"}。
  • python work/shortlist.py → output/shortlist.jpg(すべてのカット位置のフレーム)。レンダリング前にユーザーに表示します。

4. レンダリングとQC

  • python build.py [horizontal|vertical|vertical-full] — セグメントごとのキャッシュを work/seg に、xfadeチェーン、loudnorm −14 LUFS、x264。
  • EDIT=other.json OUT_SUFFIX=-v2 python build.py でメインの編集に触れずに代替編集をレンダリングします。
  • すべてのレンダリングをQC: nb_frames == duration*30(xfadeチェーンはフレームを落とす可能性あり)、blackdetect カウント0、ebur128 ≈ −14 LUFS、およびフレームのタイルシート(fps=1/5,tile=8x6)で回転やタイトルの切り捨てを目視確認。
  • ffmpeg 7以降は非推奨の -filter_complex_script よりも -/filter_complex file を推奨します。

5. ビート同期リール(IG / TikTok / FB)— reel.py + reel.json

  • python reel.py → output/reel.mp4(約45秒)、build.pyのセグメントレンダラー上に構築。
  • カットは正確にビートグリッド上に配置されます(bpm ヒント、自動位相、フレーム丸めカット時刻)。テンポを再確認: 単純な推定器はしばしば半分/倍(85 vs 154)を返します。
  • 最初の1秒は最も驚くべき瞬間で、"POV: …" の行を付けます。4ビートカット、ヒーローモーメントには6~8ビート、すべてのクリップにスロープッシュイン、セクション開始時にホワイトフラッシュ。
  • テキスト: 太いサンセリフ、白に太い黒アウトライン、上部から約24%(TikTok/IGボタンに被らない位置)、スライドアップフェード。合計5~7行の短いテキスト。最後の行はイベント名。

6. ミーム/モーションカット — motion.py + motion.json(ユーザーがミーム/ステッカーを要求した場合のみ)

  • 多くの人は、このスタイルは心のこもったイベントにはやりすぎだと感じます。デフォルトではセクション3~5を使用します。
  • 1つの長い安定したトラック(約3分)をチェーンせずに使用。ビートグリッドはコムフィルター検索で検出します。
  • クリップごと: beats, speed(0.5スローモーション / 2早送り), freeze(ビート数; テープストップ+無音+彩度低下), cap ステッカー(角丸、傾き、弾むポップ、カラー絵文字), day スラムタイトル+ウーッシュ効果, title, verse, shake, punch, flash, zoom。
  • レンダリングが強制終了された場合、ffprobeが失敗したクリップファイルを削除してから再実行してください(キャッシュが再利用されます)。

7. 縦長・ソーシャル配信

  • 誰かが16:9編集を承認し、9:16を要求した場合、同じ編集を縦長で提供します(python build.py vertical-full)。承認済みの編集を再スタイルしないでください。「もっと魅力的にして」は研磨のみを意味します。
  • プラットフォーム(特にFacebook)は無許可音楽を含む投稿をミュートします。オリジナルサウンド版("music": null の編集)や無音コピー(ffmpeg -i in.mp4 -an -c copy out.mp4)を提供し、プラットフォームのライセンスライブラリから音楽を追加できるようにします。
  • 最終研磨: eq=contrast=1.07:saturation=1.2:gamma=0.97,colorbalance=rm=0.03:bm=-0.03:rh=0.02:bh=-0.02,unsharp=5:5:0.45,vignette=angle=PI/5.5 + オーディオ highpass=80,dynaudnorm,acompressor,loudnorm=I=-14。

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル