Rough cut(ラフカット):無駄を削る
編集者はこれをアセンブリおよびラフカットと呼びます。使えるすべてのラインが順番に配置され、居場所に値しないものはすべて削除されます。完成したビデオではありません。すべての秒が話者がそのラインをうまく話しているバージョンであり、後の工程(ペーシング、カラー、グラフィック、サウンド)がよい素材で機能するようにするものです。
その背後にあるアイデア:波形ではなく単語を編集する。すべての単語に開始時間と終了時間があるトランスクリプトを取得し、それを読んで保持するものを決定し、タイミングに従ってカットが行われます。Descript、PremiereやResolveのテキストベース編集はこのように動作します。このスキルは、それらが行わない2つのことを追加します:すべてのカットを実際のサウンドにスナップし、レンダリングをもう一度聞いてチェックします。
セットアップ(一度だけ)
sh ~/simcraft/skills/rough-cut/setup.sh
このファイルの隣にWhisper(Apple Siliconではmlx-whisper、それ以外ではfaster-whisper)を使用する.venvを作成します。ffmpegが必要です:ffmpegがPATHにあるか、$FFMPEG、または~/neatlogs-motion/ffmpeg。以下のすべてのスクリプトを~/simcraft/skills/rough-cut/.venv/bin/pythonで実行してください。
ワークスペース
動画ごとに1つのフォルダ。ユーザーが作成していない場合は、~/Movies/edits/YYYY-MM-DD-<slug>/を作成し、生ファイルをraw/にコピー(移動はしないでください)します。スクリプトはその隣にaudio/、cuts/、renders/を書き込みます。raw/内のものは決して変更されません。
パイプライン(順番通り)
1. 文字起こし
python scripts/transcribe.py <workspace> [--lang en]
audio/words.json(すべての単語:開始、終了、テキスト、確信度)とaudio/transcript.txt(テイクごとに1行)を書き出します。MシリーズMacでは2分のフッテージあたり約1分かかります。
英語の場合は--lang enを指定(より正確)。ヒンディー語/英語の混合音声の場合は省略。
正確さを保つ仕組み(それぞれ実際のフッテージで遭遇した問題を修正):
- 各テイクは個別に文字起こしされる。 オーディオは0.5秒以上のポーズごとに分割されます。ファイル全体を一度に文字起こしすると、Whisperは5回言われた行を1回しか書き出さないため、余分なテイクには単語がなくなりカットできなくなります。
- フィラーはトランスクリプトに残される。 Whisperはデフォルトで「えーと」「あー」を削除します。ためらいだらけのプロンプトでそれらを復活させ、カットできるようにします。
- 文字起こしのループは破棄される。 Whisperはノイズ上でフレーズを何十回も繰り返すことがあります(「there you go there you go ...」)。1秒間に7語以上はあり得ないため、それらの行は破棄されます。
2. カットを検出
python scripts/find_cuts.py <workspace> [--gap 0.35] [--keep-fillers]
cuts/edl.json(保持するピースの順序付きリスト)とcuts/cut_sheet.md(各カットの理由と、確認すべき低確信度の単語)を書き出します。
| カット | ルール |
|---|---|
| 無音 | --gap(0.35秒)より長いポーズ。先頭と末尾の無音も含む。 |
| フィラー | えーと、あー、えっと、うーん、んー、ああ。 |
| 繰り返し | 連続して2回言われる単語または最大4単語のチャンク(「だからだから」):2回目を保持。 |
| リテイク | 20秒以内に同じ行が再度言われた場合、文字でマッチング(聞き間違いでもマッチ:「Vanta」/「Wanda」、「1」/「one」):最後のテイクを保持。 |
| 言い掛け | 途中で放棄され、その後完全に言われた行(「300 billionです。」の後「300 millionドルのビジネスです。」)。 |
| 同じ終わり | 先頭で言い直されているが、同じように終わる行(「それは、Vanta自身の創業者です」の後「そしてそれを言っているのは私ではなく、Vanta自身の創業者です」)。 |
| ゴースト単語 | 声が乗っていない単一の単語。Whisperが無音の中で作り出す(「ありがとう。」「ハレルヤ。」)。 |
各カットの着地点:
- すべてのエッジは、部屋に適応するしきい値で10msステップのラウドネスから測定された、声の実際の開始と停止にスナップされます。Whisperの単語時間は0.1〜0.3秒ずれることがあります。
- エッジは最大0.12秒後ろにしか移動しません。なぜなら、単語をクリップするのは息を残すより悪いからです。
- 声の前に0.06秒、後に0.10秒の間隔が残されます。
- 実際のギャップがない場合(例:「えー」が次の単語にくっついている場合)、カットはそれらの間の最も静かな10msポイントに置かれます。
- 1つの長いWhisperの「単語」の中に隠れているポーズも検出されカットされます。
3. 判断パス(本当の編集、絶対にスキップしないこと)
audio/transcript.txtの隣にあるcuts/cut_sheet.mdを読み、手でcuts/edl.jsonを修正します。スクリプトはこれらを判断できません:
- どのテイクが最適か。 デフォルトでは最後のテイクが保持されますが、最適なテイクはエネルギーがあり、きれいに終わり、笑いで壊れていないものです。あるテイクの前半ともう一つのテイクの終わりを組み合わせるのが最適な場合もあります。
- ジョークの一部であるフィラー。 パンチラインの前の意図的な「えー」は残します。
- 「like」「you know」「I mean」「basically」。 これらは自動的にはカットされません。純粋な間延びであるものだけをカットします。すべてカットすると、話者が自分らしくなくなります。
- 間としてのポーズ。 パンチラインの前、リアクションの前、カメラを見る前のポーズは残します。すべての無音が無駄とは限りません。
- 同じポイントを別の言葉で2回言うこと。 文全体をカットします。
- 非言語の瞬間。 歌、視覚的なギャグ、リアクションショットなど。音声のみが保持されるため、これらのピースは手で追加します。
- 順序。 ピースはファイル順に従います。ユーザーが希望する場合、最も強いラインを先頭に移動してコールドオープンにします。
- 「確認すべき単語」リスト。 低確信度はしばしばぶつぶつとした話し方を意味します。ラインが不明瞭な場合は、より明確なテイクを探します。
各ピースは{"clip", "in", "out", "text"}で構成され、"speed"はオプションです。カットは単語間で行います。
4. ペーシング(事前に確認)
カットシートは1秒あたりの単語数を報告します。テンポの良いトーキングヘッドコンテンツは約3.3〜3.8です。話者が遅い場合は、1.05〜1.2の速度を提案し、edl.jsonでビデオ全体またはピースごとに"speed"を設定します。ピッチは変わりません。音楽やリアクションを速くしないでください。
5. プレビューレンダリング
python scripts/render.py <workspace> --w 854 --v 1 [--aspect 9:16]
480pのプレビューがrenders/v1_854.mp4に出力されます。ノートのラウンドごとに--vを上げて、古いバージョンを残します。
- 各ピースは正確なフレーム数と非圧縮オーディオでレンダリングされ、その後すべてのピースがデコードによって結合されます。ストリームコピー結合ではカットでフレームがドロップされ、オーディオが数分で約2秒ずれます。
- 各ピースには12msのフェードインと20msのフェードアウトが適用され、カットでクリック音が発生しません。
- 異なる形状のクリップは、黒いバーの代わりにそれ自身のぼかしコピーの上に配置されます。
6. 検証(常に、ユーザーに見せる前に行う)
python scripts/verify.py <workspace> --v 1 [--lang en]
レンダリングをもう一度、ピースごとに聞き、カットリストと比較し、cuts/verify_v1.mdを書き出します。レポートには4つのセクションがあります:
- 音声が続いている間にカットが入る場合: Whisperに依存しないサウンドテスト。これが本当のクリップ単語検出器です。edl.jsonでそのエッジを移動してそれぞれ修正します。
- 欠落単語: 期待されるが聞こえない。
- 予期しない単語: フィラーやリテイクの一部が漏れている。
- 聞き間違い: 2つのトランスクリプトが文言で一致しない。それは通常、ぶつぶつとした話し方であり、カットの問題ではありません。
クリーンなオーディオの場合、目標は単語の100%存在、音声内カット0、予期しない単語0です。ノイズやぶつぶつしたオーディオでは、実際には聞き間違いである欠落/予期しないペアがいくつか生じます。サウンドテストを優先してください。
見つかった問題を修正し、再度レンダリングし、再度検証します。
7. ユーザーに表示、そして最終版
- ユーザーに伝える:前後の長さ、カット数、検証結果、そしてあなたが下した判断(どのテイクを保持したか、意図的に保持したポーズなど)。
- 次のバージョンを作成する前に、ユーザーのノートを記録します。
- ユーザーがプレビューを承認した後にのみ:
python scripts/render.py <workspace> --w <ソース幅> --v N。
実際のフッテージでの結果
ヘビーリテイク(あるラインを9テイク、別のラインを4テイク)のある3分間の生トーキングヘッドフッテージで、2分55秒のトークが36秒になりました。すべてのラインの最後のクリーンテイクを保持し、検証では単語の100%存在、音声内カット0、漏れ0を確認しました。
ユーザーの好み
- テンポよく。単語間のギャップ上のジャンプカットは良いが、一定の交互パンチインズームは良くない。
- 罵り、冗談、面白い部分は残す。決して個性をきれいにしない。
- この段階ではスウッシュ音やカラーグレーディングは不要。
- ユーザーが「良い部分だけ、最大X分で」と頼んだ場合は、ポーズだけでなく瞬間全体をカットする。