Agent Skills by ALSEL
汎用音声・動画・メディア⭐ リポ 317品質スコア 95/100

clipify

ビデオから最も面白い瞬間を検出し、スタンドアロンクリップとしてカットできます。オプションで16:9から9:16へのリフォーマット(フェイスパンまたはスプリットスクリーン)に対応し、Opus風の単語ごとのキャプションを焼き込みます。ユーザーが「clipify」「このビデオからクリップをカットして」「これからショーツを作って」「面白い瞬間を見つけて」「9:16にリフレーミングして」「縦型クリップ」と言及したり、ビデオファイルパスを貼り付けてSNS対応のクリップを求める場合に使用します。

description の原文を見る

Find the funniest moments in a video, cut them as standalone clips, optionally reformat 16:9 → 9:16 (face-pan or split-screen), and burn opus-style word-by-word captions. Use when the user mentions "clipify," "cut clips from this video," "make shorts from this," "find funny moments," "reframe to 9:16," "vertical clips," or pastes a video file path and wants social-ready cuts.

SKILL.md 本文

Clipify

動画の中で最も面白い瞬間を見つけ、スタンドアロンのクリップとしてカットし、必要に応じて 16:9 → 9:16 にリフォーマット(フェースパンまたはスプリットスクリーン)し、Opus スタイルのワードバイワードキャプションを焼き込みます。

入力

  • ビデオファイルパス(ユーザーが提供します。ない場合は尋ねます)
  • オプション: リクエストされたフォーマット(9:16、16:9、1:1) — 指定されていない場合は、候補を選んだ後に尋ねます
  • オプション: サブタイトルスタイルの好み — 指定されていない場合は、キャプション追加前に尋ねます

ツール(最速パスのみ使用)

  • Whisper: whisper --model tiny.en --word_timestamps True --output_format json (約 10 倍高速、品質は英語には問題なし)。非英語の場合: --model base(--language は削除)
  • ffmpeg: デコードに -hwaccel videotoolbox を追加し、レンダリングに -preset ultrafast を追加します。最終マスターには -c:v libx264 -crf 20 を使用します。
  • Numpy オーディオアライメント用(FFT 相互相関)。scipy/cv2 は不要です。
  • スクリプト: <skill-dir>/scripts/ (<skill-dir> はこの SKILL.md を含むディレクトリ — 通常は ~/.claude/skills/clipify/)
    • analyze.py — 2 つの ROI モーションファイルからスピーカータイムライン
    • build_pan.py — ffmpeg クロップ x 式とハードカット
    • build_ass.py — Whisper JSON から Opus スタイルの ASS キャプション
    • audio_align.py — 長いソースでのサブクリップのオフセット検出

作業ディレクトリ: /tmp/clipify/ (開始時に mkdir し、デバッグ用に成果物を残します)


ワークフロー

ステップ 1 — 最も面白い部分を見つける

mkdir -p /tmp/clipify
ffmpeg -y -hwaccel videotoolbox -i "$VIDEO" -vn -ac 1 -ar 16000 /tmp/clipify/audio.wav
whisper /tmp/clipify/audio.wav --model tiny.en --word_timestamps True --output_format json --output_dir /tmp/clipify --language en

結果の JSON(または .txt)を読み、3〜5 個の候補クリップを選びます。面白さの信号をスキャンします:

  • パンチラインとリアクション: 「what」「wait」「no way」「laughter」「haha」「swearing」などの単語
  • 反転の瞬間: セットアップの質問 → 予期しない答え
  • 気まずい沈黙: Whisper セグメントに長いギャップがある、またはフィラー(「uh」「um」)
  • セルフロースト / 名台詞: スタンドアロンで成立する短い叙述文
  • オーディオピーク: ffmpeg -af volumedetect で検出、または急速な応答(Whisper セグメントが短く交互)を探す

各候補について、以下を提案します: [開始、終了、なぜ面白いのか、推奨タイトル]。10〜25 秒のクリップを目指します。リストを表示し、ユーザーに確認/選択させます。

ステップ 2 — 選んだ各クリップをトリム

ffmpeg -y -ss "$START" -t "$DURATION" -i "$VIDEO" -c copy /tmp/clipify/clip_$N.mp4

(-c copy を使用して即座にトリムします。カットがフレームアキュレートである必要がある場合のみ再エンコードします)

ステップ 3 — 出力フォーマットを決定

ユーザーに尋ねます(すでに指定されている場合はスキップ): 「9:16(TikTok / Reels)、16:9(YouTube)、1:1(Insta フィード)?」

ステップ 4 — 16:9 → 9:16 の場合: フェースパン vs スプリットスクリーン

ffprobe でソースアスペクト比を検出します。ソースが 16:9 でターゲットが 9:16 の場合、尋ねます:

「2 つのオプション: (a) 話している人を追う hard-cut パン(一度に 1 つの顔のみ画面に表示)、または (b) スプリットスクリーン両方の顔が見える積み重ね。どちらを希望しますか?」

顔が 1 つだけ(シングルトーカークリップ)の場合、質問をスキップします。シングルトーカーの場合は、単に中央クロップします。

ステップ 4a — フェースパン(高速カット会話型トーキングヘッド対話に推奨)

  1. 2 つの顔 ROI を特定します。 1 フレームをサンプリング: ffmpeg -ss <middle> -i <clip> -frames:v 1 /tmp/clipify/probe.jpg。それを読みます。ソースのピクセル空間で各顔の口+顎の領域を x,y,w,h として目測します(cv2 は不要 — カメラはクリップ内で静止、1 フレームで十分)。ボックスを描画して確認します:

    ffmpeg -i probe.jpg -vf "drawbox=x=$LX:y=$LY:w=$LW:h=$LH:color=cyan@0.9:t=4,drawbox=x=$RX:y=$RY:w=$RW:h=$RH:color=magenta@0.9:t=4" verify.jpg
    

    最大 2 回 反復します。ボックスは口 + 顎をカバーし、手/マイクを避けるべきです。過度にチューニングしないでください — フレーム差分は許容度が高いです。

  2. 各 ROI でフレームごとのモーションエネルギーを抽出します:

    ffmpeg -y -i clip.mp4 -filter_complex "
    [0:v]split=2[a][b];
    [a]crop=$LW:$LH:$LX:$LY,format=gray,tblend=all_mode=difference,signalstats,metadata=mode=print:key=lavfi.signalstats.YAVG:file=/tmp/clipify/L.txt[la];
    [b]crop=$RW:$RH:$RX:$RY,format=gray,tblend=all_mode=difference,signalstats,metadata=mode=print:key=lavfi.signalstats.YAVG:file=/tmp/clipify/R.txt[ra]
    " -map "[la]" -f null - -map "[ra]" -f null -
    
  3. スピーカータイムラインを構築します(最小滞在時間 1.0 秒 — 短い割り込みは前のスピーカーにマージされます):

    python3 <skill-dir>/scripts/analyze.py /tmp/clipify/L.txt /tmp/clipify/R.txt 1.0 > /tmp/clipify/segments.json
    
  4. ソースから 9:16 の垂直ストリップのパン x 座標を選択します。 ソース W=1920、ターゲット W=1080 の場合、クロップストリップ幅 = 608。

    • LEFT_X = face_left_center_x - 304 (≥ 0 でクランプ)
    • RIGHT_X = face_right_center_x - 304 (≤ source_W - 608 でクランプ)
  5. hard-cut x 式を生成してレンダリングします:

    EXPR=$(python3 <skill-dir>/scripts/build_pan.py /tmp/clipify/segments.json $LEFT_X $RIGHT_X)
    ffmpeg -y -hwaccel videotoolbox -i clip.mp4 -filter_complex \
      "[0:v]crop=608:1080:x='$EXPR':y=0,scale=1080:1920:flags=lanczos[v]" \
      -map "[v]" -map 0:a -c:v libx264 -preset fast -crf 20 -pix_fmt yuv420p \
      -c:a aac -b:a 192k /tmp/clipify/clip_panned.mp4
    

    ソース 1920×1080 を想定。4K ソースの場合は、最初にダウンスケールするか、すべての座標を 2 倍にします。

ステップ 4b — スプリットスクリーン(常に両方の顔が見える)

2 つの積み重ねたタイル、各 1080×960。アクティブなスピーカーのタイルが上にあり — スピーカー変更時にオーバーレイが反転します。

[0:v]split=2[a0][a1];
[a0]crop=Wcrop:Hcrop:LX_tile:LY_tile,scale=1080:960,split=2[lt0][lt1];
[a1]crop=Wcrop:Hcrop:RX_tile:RY_tile,scale=1080:960,split=2[rt0][rt1];
[lt0][rt0]vstack[layoutL];
[rt1][lt1]vstack[layoutR];
[layoutL][layoutR]overlay=0:0:enable='<RIGHT_SPEAKER_ENABLE>'[v]

segments.json から <RIGHT_SPEAKER_ENABLE>between(t,a,b)+between(t,a,b)+... として右スピーカーセグメント上に構築します。タイルクロップは各顔の周囲 ~720×640 をターゲットにします(1080×960 に合わせるために 1.125:1)。

ステップ 5 — サブタイトルを追加

一度尋ねます(ユーザーがすでにスタイルを指定していない場合のみ):

「3 つのサブタイトルスタイル: opus(大きな太字の白、黄色のアクティブワードハイライト)、karaoke(4 ワードチャンク、緑のハイライト)、minimal(クリーンな Helvetica、ハイライトなし)。または、好きな例を貼り付けてください。」

参照画像/例を貼り付けた場合: フォント、サイズ、ウェイト、色、位置、アニメーションをできるだけ一致させます — カスタム ASS を手書きするか、build_ass.py を拡張します。

そうでない場合はプリセットを使用します:

# トリムされたクリップで whisper を再実行し、クリップ開始を基準とした正確なタイムスタンプを得ます
whisper /tmp/clipify/clip_panned.mp4 --model tiny.en --word_timestamps True --output_format json --output_dir /tmp/clipify --language en
python3 <skill-dir>/scripts/build_ass.py /tmp/clipify/clip_panned.json /tmp/clipify/captions.ass opus

キャプションを焼き込みます:

ffmpeg -y -i /tmp/clipify/clip_panned.mp4 -vf "subtitles=/tmp/clipify/captions.ass" \
  -c:v libx264 -preset fast -crf 20 -c:a copy "$OUTPUT.mp4"

ステップ 6 — 配信

  • 各出力を <source_dir>/clipify_out/ に保存(ない場合は mkdir)
  • クリップごと 1 行を出力: 名前、期間、何が面白かったのか、出力パス
  • open <path> で最初の出力を開き、ユーザーが確認できるようにします
  • 反復を提案(異なるスタイル、異なる ROI、スプリットスクリーンに切り替え、キャプションの時間を調整)

落とし穴(以前の実行からの教訓 — 繰り返さないでください)

  • ROI を過度にチューニングしないでください。 最大 2 回の反復。モーション差分は許容度が高く — 口+顎をカバーするより広い ROI は、完全に口中心でなくても問題なく機能します。
  • クリップ内のシーンカットに注意してください。 ffmpeg -filter:v "select='gt(scene,0.3)',showinfo" -f null - を実行してカットをカウントします。16:9→9:16 クリップに多くのカットがある場合、固定顔 ROI は支配的なシーンにのみ機能します。ユーザーに警告し、シングルテイククリップを選択するか、カット中のオフセンタースレーミングを受け入れるか、いずれかを提案します。
  • ソース解像度は重要です。 ソースが 4K の場合、最初に 1920×1080 にダウンスケール(高速、9:16 出力に問題なし)するか、すべての ROI/パン座標に 2 を掛けます。
  • ソースの焼き込まれたサブタイトル。 一部の「ロー」クリップにはまだサブタイトルがあります。その場合は、オーディオ相互相関(audio_align.py)を経由してノーサブマスターを見つけ、そこからトリムします。
  • 短いクリップで十分な場合は、フル長ソースで whisper を実行しないでください。 ステップ 2 の後にトリムされたクリップで Whisper を実行します。面白い瞬間を見つけるためにトランスクリプトが必要な場合のみ、ステップ 1 でフルソースで whisper を実行します。
  • 計画を 1 行で述べてから実行します。 反復のたびにナレーションしないでください。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
louisedesadeleer
リポジトリ
louisedesadeleer/clipify
ライセンス
MIT
最終更新
2026/5/5

Source: https://github.com/louisedesadeleer/clipify / ライセンス: MIT

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: louisedesadeleer · louisedesadeleer/clipify · ライセンス: MIT