Communitygithub.com

0xSero/video-edit

生のスクリーン/OBS/トーク録画を、プロフェッショナルなアップロード用に整えます。トランスクリプトに基づくカット、無音・静止画除去、プライベートな瞬間のカット、画面上の情報漏洩の墨消し、音声強化、印象的なオープニング、確認済みレンダリング、そしてチャプター・タイトル・タグ・説明文・字幕・サムネイルを生成し、~/Downloads に配置して開きます。ユーザーが「録画した動画を編集して」「無音をカットして」「恥ずかしい部分を削除して」「情報が漏れないようにして」「YouTube に投稿できる状態にして」と言ったときに使用します。スライドからプロモーション/モーション・グラフィックス動画を作成するものではありません。サムネイル単体の場合は youtube-pack を使用してください。

video-edit とは?

このスキルは、生のスクリーン/OBS/トーク録画から、プロフェッショナルなYouTubeアップロード用の動画を編集・生成するエンドツーエンドのワークフローです。このスキルは、トランスクリプトに基づくコンテンツのカット、無音・静止画の除去、プライバシー保護(個人情報の墨消し・Webカメラ映像のカット)、音声強化(DeepFilterNet3)、印象的なオープニング、検証済みレンダリング、そしてチャプター、タイトル、タグ、説明文、字幕、サムネイルの生成を自動化します。主な対応プラットフォームはmacOSで、ffmpeg、mlx_whisper、DeepFilterNet3、Apple Visionなどのツールチェーンを利用します。ユーザーが「録画した動画を編集して」「無音をカットして」「恥ずかしい部分を削除して」「情報が漏れないようにして」「YouTube に投稿できる状態にして」といった要求をしたときに使用します。このスキルは、生の録画ファイルを決して変更せず、作業ディレクトリでコピーを操作し、最終的な確認済みの動画とメタデータを `~/Downloads` に出力します。

対応~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/0xSero/video-edit/tree/HEAD

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

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

ドキュメント

動画編集(スクリーン / OBS / トーク録画)

スクリプトキット: このスキルの scripts/ ディレクトリ(prep.sh, transcript_txt.py, ocr_scan.py, cam_flags.py, df_enhance.py, build_edl.py, render.py, verify_output.py, chapters.py, overview.py, job.example.json, selftest.sh)。これらは <workdir>/scripts/ にコピーして実行します。ジョブがスキルディレクトリに依存しないようにするためです。scripts/selftest.sh は、インストールがエンドツーエンドで数分で動作することを確認します。

入力

  • <src>: 録画ファイル。通常は ~/Desktop/*.mov の中で最も新しいもの(OBS の命名規則 YYYY-MM-DD HH-MM-SS.mov)。複数の最近の録画がある場合は、パイプラインを開始する前にどれを編集するか確認してください。間違った動画を編集すると1時間の無駄になります。
  • <target_minutes>: 指定がない場合は確認します。通常は45〜90分のソースから20〜30分を目安にします。
  • <workdir>: 新しいスクラッチディレクトリ。例: /tmp/<session>/edit。
  • ツールチェーン: ffmpeg 6以上、python3、mlx_whisper、DeepFilterNet3、Pillow/numpy/soundfile、Apple Vision(pyobjc-framework-Vision/-Quartz)。

手順

  1. 偵察、ソースには決して触れない。 ffprobe <src>(解像度、fps、音声)。<workdir> 内のコピー/抽出物のみを操作します。
  2. 準備。 prep.sh "<src>" $W: orig48.wav、mono16.wav、frames/(2秒に1フレーム)、camall/(Webカメラクロップ、1 fps、解像度から自動的にジオメトリを導出)、sheet_overview.jpg、silences_raw.txt(診断用のみ)、および transcript.json(mlx_whisper large-v3-turbo、単語タイムスタンプ付き、約4分)。Whisper は prep が戻った後もバックグラウンドで実行され続けます。すぐに df_enhance.py orig48.wav df_enhanced.wav(DeepFilterNet3、CPUで約6分)を開始してください。これは独立した処理です。
  3. トランスクリプト全体を読む(transcript_txt.py ... --from/--to を使用して3チャンク)。キープ範囲(ソース秒)を job.json -> keep に書き込みます。無音のトリミングはわずかです(47分中約2分)。実際の時間短縮はコンテンツの判断によります。Whisper は自己通知します。つまり、同じフレーズが10回以上繰り返される、または空のセグメントが続く場合、それは無駄な部分なのでカットします。
  4. ビジュアルスタティックパス。 「何も起こっていない」とは、多くの場合、視覚的に静止していることであり、無音ではありません。0.5 fps のフレームでフレーム差分を取ります。約10秒のウィンドウでピクセルの変化が1%未満 = 非アクティブ。1秒以下のブリップで分割されたランをマージ。カットするには4秒以上必要。0.5秒のハンドル。点滅するカーソル/スピナーはアクティビティの偽装です。マスクするかしきい値を上げます。中間フレームの変化と元に戻るバーストを確認します。タイピングはノイズであり、無音ではありません。ゲートは生の silencedetect ではなく、強化された トラックのRMS(pause.loud_db)を使用します。
  5. オープニング。 最初の実際のコンテンツより前のすべてをカットします。開始が遅い/退屈な場合は、最も興味深いデモから始めます。必要に応じて、1〜2のエキサイティングなクリップでコールドオープンし、その後にイントロをスピードアップします。壁紙/黒い画面で始めることは絶対に避けてください。最初の30秒がガタガタだと、質の低い動画と思われます。
  6. 漏洩スキャン(読みながら実行)。 ocr_scan.py scan を run の後に frames/ に対して実行します。IPv4/v6、*.ts.net、メールアドレス、APIキー、SSH関連資料を検出します。ターミナル/設定が多い範囲では、ocr_scan.py dense src.mov dense 600:60 ... を使用して高密度(2 fps)パスを実行します。静的テキスト -> boxes(ベタ塗り)。スクロールするターミナル出力 -> ペイン全体をぼかします(blur ウィンドウ + blur_regions、ソースピクセル単位)。サンプル間のテキストを行単位のボックスで見逃すことを防ぎます。127.0.0.1/localhost は問題ありません。すべてのウィンドウを job.json に記録します。
  7. プライバシーカット(Webカメラ)。 cam_flags.py(Vision を使用して手が口の近くにあるか検出)+ cam_flags.py --sheet S:DUR で、フラグが立った各クラスターの2 fpsのズームシートを生成します。ユーザーが公開したくない瞬間(一時停止中の手と顔、机を離れる、フレーム内の別の人物、顔全体のセグメント)をカットします。通常の考え事のポーズや小さなジェスチャーは問題ありません。ジェスチャーのために文の途中でカットすることは絶対にしないでください。最も近い文の境界にスナップし、何が失われたかをメモします。
  8. ユーザーのタイムスタンプカットは文字通りに適用します。 「cut 0000 - 01:12」 -> job.cuts(または keep)に入れ、正確に適用し、その後、シーム周辺のペーシングを再確認します。
  9. オーディオマスター。 健全性確認: 強化版とオリジナルの相関が0.95を超えていること(df_enhance.py が表示します)。デフォルトの audio_chain は、ハイパス75、220 Hz / 3.2 kHz / 9 kHz 周辺のカット/ブースト、ディエッサー、3:1コンプレッサーです。持続的なファンノイズがある場合は、equalizer 項を追加してノッチをかけます。render.py が2パス loudnorm を -16 LUFS / -1.5 dBTP に適用します。未加工のマイク音声はオーディオトラック2として保持されます。
  10. EDL + レンダリング。 build_edl.py -> segments.json(キープ内の0.7秒を超えるポーズは0.4秒に短縮。プローブされたフレームレートにスナップ。0.3秒未満はドロップ)。render.py: h264_videotoolbox エンコードをグループ化して並列実行、-c copy で結合、両方のトラックを多重化。グループごとに再開可能。グループが失敗した場合は修正して再実行、変更のないグループはスキップされます。特に指定がない限り1080pで提供します(4Kはレンダリング時間が2倍になるだけでメリットはありません)。
  11. 提供前に確認。 verify_output.py は、フレーム数がEDLと一致し、両方のオーディオトラックの長さが動画の長さと一致し、出力のOCR(墨消しウィンドウ全体で4 fps)で漏洩がゼロであることが確認されない限り、ゼロ以外の終了コードを返します。また、各プライバシーカットの出力フレームと0:00〜1:00のフレームを取得して目視確認します。素材が機密性の高い場合は、--full を使用してファイル全体の漏洩スイープを実行します。
  12. 新しいカットを再トランスクリプト。 トランスクリプト、字幕、チャプターは出力のタイムラインに一致している必要があり、ソースのものではありません。SRT/チャプターを書き込む前に、カット済み動画に対してWhisperを再実行するか(または chapters.py を使用してEDL経由で再マッピング)します。ソーストランスクリプトから取得したSRT時間をそのまま使用しないでください。
  13. メタデータ + 納品。 二度言われなくても実行: チャプタータイムスタンプ(chapters.py、3以上、最初は0:00)、2〜3のタイトル候補、500文字未満の約30のタグ(必要な場合は+2のタグ/説明バリエーション)、説明文、言語ごとのSRT(約42文字/行、多言語対応はリクエストに応じて)、すべてプレーンテキスト。サムネイルは youtube-pack を使用: スタイルを把握するためにユーザーの最後の10個のサムネイルを読み込みます。デフォルトは白/クリーム色の背景に黒いテキスト。顔は要求がない限り使用しません。ロゴ/テキストは大きく、すっきりと。その後、<output>.mp4(およびSRT/メタデータ)を ~/Downloads に移動し、ファイルを開くか、フォルダをデフォルトアプリで開きます。

出力

  • <Topic> - YYYY-MM-DD - edit.mp4(1080p、2オーディオトラック)が ~/Downloads に配置され、デフォルトアプリで開かれます。
  • <workdir>: job.json、segments.json、group_bounds.json、vf_<n>.txt、墨消し/プライバシーログ。
  • ~/Downloads: SRTファイル、metadata.txt(タイトル、説明文、タグ、チャプター)。
  • オプション(リクエストに応じて): 同じソースから分割されたトピック別サブ動画。それぞれに独自のチャプターがあります。

連携

whisper/DFN3 (キット内) -> video-edit (確認済みmp4を~/Downloadsに) -> youtube-pack (thumbnail.png) -> ユーザーの他の動画のように設定されたYouTube Studioへのブラウザアップロード。

ルール

  • ソース録画ファイルを決して変更しないでください。
  • 目標時間はあくまで目標です。コンテンツを削らずに短縮できない場合は、少し長めに納品し、次の2つのカット案を示します。
  • ポーズをさらに削る前に、脱線部分全体をカットします。ハードウェアの話、ライブデモ、正直な注意点、まとめは残します。
  • 常に最後に行うこと: ~/Downloads に移動し、開く。
  • 正直に報告する: あなたは結果を聞くことができません。その旨を伝え、トラック2を参照するように促します。
  • 別録りの音声(Discord/Craig)は通常存在しません。Desktop/Downloads/iCloud/ボイスメモを確認し、存在しない場合はOBSマイクを使用したことを伝えます。
  • 空き容量を要求された場合: 未承認の古いドラフト/バリアントを削除し、ソースと最終版を保持します。
  • 複数人ポッドキャスト: 正しいオーディオトラックを見つけ(通常は多数の中の2つ)、音声を正しい話者にマッピングし、話している人に合わせて映像を切り替え、トランジションをきれいにします。
  • レンダリングが完了したからといって編集が完了したと主張しないでください。verify_output.py + 目視確認したフレームが解決します。

確認

  • verify_output.py が PASS(フレーム数、2つのオーディオトラック、ウィンドウ内に漏洩なし)を表示し、終了コード0で終了します。
  • 0:00〜1:00と各プライバシーカットのフレームを目視確認します(verify_output.py --sheet 0:60)。
  • SRTの再トランスクリプトをカット後の動画とスポットチェックします。
  • ffprobe で納品ファイルを確認: 長さ、解像度、fps、2つのオーディオストリーム。

既知の失敗

  • 間違った動画を編集 -> パイプライン前に最新/トピックが一致していることを確認します。
  • 字幕/チャプターがソースタイムラインのまま -> カット後に再トランスクリプトします(手順12)。
  • 出力にホスト名が表示される -> OCRサンプル間のスクロールテキスト。ペイン全体をぼかし、ウィンドウを広げ、出力側でOCRを実行します。
  • Silencedetect がタイピング/動画再生をカットする -> 無音だけでなく、強化オーディオのRMS(pause.loud_db)でゲートします。
  • ガタガタの黒いオープニング -> 出力の0:00〜1:00フレームを確認し、実際のコンテンツでコールドオープンします。
  • cp -i 上書きプロンプト / サンドボックスTCCが ~/Downloads をブロック -> サンドボックスを無効にして /bin/cp を使用します。
  • ffmpeg フィルターが約100個以上の between() 項で停止する(「Cannot allocate memory」)-> render_groups を減らします。
  • 点滅カーソルがフレーム差分でアクティビティとしてカウントされる -> マスク/しきい値を調整し、中間フレームを確認します。
  • render.py フレーム不一致 -> 連結を拒否します。render_<n>.log を読みます(非キーフレームの前の -ss、壊れたデコーダー)。
  • transcript.json を読んだときに Whisper がまだ実行中 -> transcript_txt.py が空のセグメントを報告します。whisper.log が終了するのを待ちます。

例

  • 2026-09-02 トーク、47分 -> 26分: 32のキープ範囲、2つのプライバシーカット(9:52-9:58、26:08-26:14)、2つのぼかしウィンドウ + 1つのボックス(*.ts.net ホスト名)、レンダリング約2時間(実時間)、出力側OCRでのみ漏洩をキャッチ。
  • 2026-09-24 OBSセッションの教育: ユーザーが最初のカットを拒否(「背景ノイズ、タイピング、始まりが非常に退屈」)-> タイピングノイズを除去、より良いオープニングを選択、トランスクリプトをやり直し、その後 0:00-1:12 を文字通りヘッドカット、漏洩スキャン、より大きなロゴの白/クリーム色のサムネイル、2つのメタデータバリアント、Downloadsに移動。
  • ポッドキャスト(2026-09-18): 1時間40分の動画 + 5つの候補オーディオファイル -> 話者ごとの正しい2トラックを特定、音声を動画にマッピング、1080p、ヘッドトリム、SRT + スペイン語/アラビア語/ヒンディー語翻訳、チャプタータイムスタンプ、両方の話者が写ったサムネイル、上部にテキスト、黒背景なし。

関連スキル