動画編集(スクリーン / 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。- ツールチェーン:
ffmpeg6以上、python3、mlx_whisper、DeepFilterNet3、Pillow/numpy/soundfile、Apple Vision(pyobjc-framework-Vision/-Quartz)。
手順
- 偵察、ソースには決して触れない。
ffprobe <src>(解像度、fps、音声)。<workdir>内のコピー/抽出物のみを操作します。 - 準備。
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分)を開始してください。これは独立した処理です。 - トランスクリプト全体を読む(
transcript_txt.py ... --from/--toを使用して3チャンク)。キープ範囲(ソース秒)をjob.json -> keepに書き込みます。無音のトリミングはわずかです(47分中約2分)。実際の時間短縮はコンテンツの判断によります。Whisper は自己通知します。つまり、同じフレーズが10回以上繰り返される、または空のセグメントが続く場合、それは無駄な部分なのでカットします。 - ビジュアルスタティックパス。 「何も起こっていない」とは、多くの場合、視覚的に静止していることであり、無音ではありません。0.5 fps のフレームでフレーム差分を取ります。約10秒のウィンドウでピクセルの変化が1%未満 = 非アクティブ。1秒以下のブリップで分割されたランをマージ。カットするには4秒以上必要。0.5秒のハンドル。点滅するカーソル/スピナーはアクティビティの偽装です。マスクするかしきい値を上げます。中間フレームの変化と元に戻るバーストを確認します。タイピングはノイズであり、無音ではありません。ゲートは生の
silencedetectではなく、強化された トラックのRMS(pause.loud_db)を使用します。 - オープニング。 最初の実際のコンテンツより前のすべてをカットします。開始が遅い/退屈な場合は、最も興味深いデモから始めます。必要に応じて、1〜2のエキサイティングなクリップでコールドオープンし、その後にイントロをスピードアップします。壁紙/黒い画面で始めることは絶対に避けてください。最初の30秒がガタガタだと、質の低い動画と思われます。
- 漏洩スキャン(読みながら実行)。
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に記録します。 - プライバシーカット(Webカメラ)。
cam_flags.py(Vision を使用して手が口の近くにあるか検出)+cam_flags.py --sheet S:DURで、フラグが立った各クラスターの2 fpsのズームシートを生成します。ユーザーが公開したくない瞬間(一時停止中の手と顔、机を離れる、フレーム内の別の人物、顔全体のセグメント)をカットします。通常の考え事のポーズや小さなジェスチャーは問題ありません。ジェスチャーのために文の途中でカットすることは絶対にしないでください。最も近い文の境界にスナップし、何が失われたかをメモします。 - ユーザーのタイムスタンプカットは文字通りに適用します。 「cut 0000 - 01:12」 ->
job.cuts(またはkeep)に入れ、正確に適用し、その後、シーム周辺のペーシングを再確認します。 - オーディオマスター。 健全性確認: 強化版とオリジナルの相関が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として保持されます。 - EDL + レンダリング。
build_edl.py->segments.json(キープ内の0.7秒を超えるポーズは0.4秒に短縮。プローブされたフレームレートにスナップ。0.3秒未満はドロップ)。render.py:h264_videotoolboxエンコードをグループ化して並列実行、-c copyで結合、両方のトラックを多重化。グループごとに再開可能。グループが失敗した場合は修正して再実行、変更のないグループはスキップされます。特に指定がない限り1080pで提供します(4Kはレンダリング時間が2倍になるだけでメリットはありません)。 - 提供前に確認。
verify_output.pyは、フレーム数がEDLと一致し、両方のオーディオトラックの長さが動画の長さと一致し、出力のOCR(墨消しウィンドウ全体で4 fps)で漏洩がゼロであることが確認されない限り、ゼロ以外の終了コードを返します。また、各プライバシーカットの出力フレームと0:00〜1:00のフレームを取得して目視確認します。素材が機密性の高い場合は、--fullを使用してファイル全体の漏洩スイープを実行します。 - 新しいカットを再トランスクリプト。 トランスクリプト、字幕、チャプターは出力のタイムラインに一致している必要があり、ソースのものではありません。SRT/チャプターを書き込む前に、カット済み動画に対してWhisperを再実行するか(または
chapters.pyを使用してEDL経由で再マッピング)します。ソーストランスクリプトから取得したSRT時間をそのまま使用しないでください。 - メタデータ + 納品。 二度言われなくても実行: チャプタータイムスタンプ(
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 + スペイン語/アラビア語/ヒンディー語翻訳、チャプタータイムスタンプ、両方の話者が写ったサムネイル、上部にテキスト、黒背景なし。