freecut
原則
- LLM は生の文字起こし+オンデマンドのビジュアルから推論する。 保持するに値する唯一の派生アーティファクトは、圧縮されたフレーズレベルの文字起こし(
takes_packed.md)です。それ以外のすべて(フィラータグ付け、リテイク検出、ショット分類、強調スコアリング)は、意思決定時に導出します。 - 音声を優先し、ビジュアルはそれに従う。 カット候補は発話境界と無音ギャップから生成します。ビジュアルへの掘り下げは意思決定ポイントでのみ行います。
- 質問→確認→実行→反復→永続化。 ユーザーが平文で戦略を確認するまで、カットに手を触れてはいけません。
- 一般化する。 これがどのような種類の動画かを前提としないでください。素材を見て、ユーザーに質問し、それから編集します。
- 芸術的自由をデフォルトとする。 このドキュメント内のすべての特定の値、プリセット、フォント、色、継続時間、ピッチ構造、技法は、実績のある1つの動画からの動作例であり、必須事項ではありません。それらを読んで何が可能で、なぜそれぞれが機能したかを理解してください。そして、素材の実態とユーザーの希望に基づいて、独自のセンスで判断してください。絶対に行わなければならないことは、下記のハードルールセクションのみです。 それ以外はすべてあなたの自由です。
- 自由に発明する。 素材がここに記載されていない技法(スプリットスクリーン、ピクチャー・イン・ピクチャー、ローワーサードのアイデンティティカード、リアクションカット、スピードランプ、フリーズフレーム、クロスフェード、マッチカット、Lカット、Jカット、ブレスに合わせたスピードランプなど)を必要とするなら、何でも構築してください。ヘルパーは ffmpeg と PIL です。それらはフォーマットがサポートするあらゆることができます。許可を待つ必要はありません。
- ユーザーに見せる前に、自分の出力を検証する。 出荷できないものは、提示してはいけません。
ハードルール(プロダクションの正確性 - 交渉不可)
これらは、逸脱すると無言の失敗や破損した出力を生み出すものです。センスではなく正確性の問題です。暗記してください。
- 字幕はフィルターチェーンの最後に適用、すべてのオーバーレイの後。そうしないと、オーバーレイがキャプションを隠します。無言の失敗。
- セグメントごとに抽出→ロスレス
-c copyで連結。シングルパスのフィルターグラフは不可。そうしないと、オーバーレイが追加されたときにすべてのセグメントが二重エンコードされます。 - すべてのセグメント境界で30msのオーディオフェード(
afade=t=in:st=0:d=0.03,afade=t=out:st={dur-0.03}:d=0.03)。そうしないと、カットのたびに聴こえるポップノイズが発生します。 - オーバーレイは
setpts=PTS-STARTPTS+T/TBを使用して、オーバーレイのフレーム0をそのウィンドウ開始位置にシフトします。そうしないと、オーバーレイウィンドウ中にアニメーションの中間が表示されます。 - マスターSRTは出力タイムラインオフセットを使用:
output_time = word.start - segment_start + segment_offset。そうしないと、セグメント連結後にキャプションがずれます。 - 単語の途中でカットしない。 すべてのカットエッジを文字起こしの単語境界にスナップします。
- すべてのカットエッジにパディングを追加する。 作業ウィンドウ:30~200ms。ASRタイムスタンプは50~100msずれるため、パディングで吸収します。テンポの速いものはより狭く、シネマティックなものはより広く。
- 単語レベルの逐語ASRのみ。 SRT/フレーズモードは不可(サブ秒のギャップデータを失う)。正規化されたフィラーは不可(編集上のシグナルを失う)。
- ソースごとに文字起こしをキャッシュする。 ソースファイル自体が変更されない限り、再文字起こししてはいけません。
- 複数のアニメーションには並列サブエージェント。 逐次処理は不可。
Agentツールを介して一度にN個を起動し、総ウォールタイムは最も遅いものと同程度にします。 - 実行前に戦略を確認する。 ユーザーが平易な英語の計画を承認するまで、カットに手を触れてはいけません。
- すべてのセッション出力は
<videos_dir>/edit/に。freecut/プロジェクトディレクトリ内には決して書き込まない。
このドキュメントの他のすべては動作例です。素材が必要とするときはいつでも逸脱してください。
ディレクトリ構成
スキルは freecut/ にあります。ユーザーの映像はユーザーが配置した場所にあります。すべてのセッション出力は <videos_dir>/edit/ に出力されます。
<videos_dir>/
├── <ソースファイル、未加工>
└── edit/
├── project.md ← メモリ、セッションごとに追記
├── takes_packed.md ← フレーズレベルの文字起こし、LLMの主要な読み取りビュー
├── edl.json ← カット決定
├── transcripts/<name>.json ← キャッシュされた正規化ASR JSON
├── animations/slot_<id>/ ← アニメーションごとのソース + レンダリング + 推論
├── clips_graded/ ← グレーディングとフェードが適用されたセグメントごとの抽出
├── master.srt ← 出力タイムライン字幕
├── downloads/ ← yt-dlp出力
├── verify/ ← デバッグフレーム / タイムラインPNG
├── preview.mp4
└── final.mp4
セットアップ
初回インストールは install.md にあります(クローン、依存関係、ffmpeg、スキル登録、APIキー)。毎セッションで再実行する必要はありません。コールドスタート時には以下を確認するだけです。
- 文字起こしバックエンドが利用可能であること。デフォルトは
whisper(無料、ローカル)です。mlx-whisper(Apple Silicon)またはfaster-whisperがインポート可能であることを確認してください。どちらもインストールされていない場合は、ユーザーにpip install mlx-whisper(またはfaster-whisper)を伝え、静かに有料バックエンドにフォールスルーしないでください。オプションのvibevoice/elevenlabsバックエンドの場合は、freecutレポジトリルートの環境変数または.envでVIBEVOICE_ASR_URL/ELEVENLABS_API_KEYを確認してください。 ffmpeg+ffprobeがPATHに存在すること。- Pythonの依存関係がインストールされていること(レポジトリ内で
uv syncまたはpip install -e .)。 - セッションでHyperFramesまたはRemotionスロットが必要な場合、Node.js + npmが利用可能であること。HyperFramesは現在Node.js 22+を必要とします。
yt-dlp、HyperFrames、Remotion、Manimは初回使用時にのみインストールされます。- 初回使用時のアニメーションセットアップは、freecutレポジトリルートではなく、スロットディレクトリ内で行われます。HyperFrames は
npx --yes hyperframes ...で呼び出せます。Remotion はnpx create-video@latestでスキャフォールドするか、プロジェクトローカルの依存関係としてインストールした後にremotion renderコマンドを使用します。 - このスキルは
skills/manim-video/をベンダー提供しています。Manimスロットを構築する際は、そのSKILL.mdを読んでください。
ヘルパー(helpers/transcribe.py、helpers/render.py など)はこのSKILL.mdと同じディレクトリにあります。それらのパスは、このファイルを含むディレクトリからの相対パスで解決してください。スキルは通常、~/.claude/skills/freecut/ または ~/.codex/skills/freecut/ にシンボリックリンクされています。
ヘルパー
transcribe.py <video>— 単一ファイルの文字起こし。--backend {whisper,vibevoice,elevenlabs}(デフォルトwhisper、ローカル+無料、単一話者)でバックエンドをプラグイン可能。vibevoiceはダイアライゼーションのためにVIBEVOICE_ASR_URLを使用します。elevenlabsはELEVENLABS_API_KEYを使用し、--num-speakersをサポートします。キャッシュされます。transcribe_batch.py <videos_dir>— 4ワーカー並列文字起こし。同じ--backendフラグ。マルチテイクに使用します。pack_transcripts.py --edit-dir <dir>—transcripts/*.json→takes_packed.md(フレーズレベル、0.5秒以上の無音または話者変更で分割)。JSONの形状が正規化されているため、すべてのバックエンドで同じように動作します。timeline_view.py <video> <start> <end>— フィルムストリップ+波形PNG。オンデマンドのビジュアルドリルダウン。スキャンツールではありません — 常にではなく、意思決定ポイントでのみ使用してください。render.py <edl.json> -o <out>— セグメントごとの抽出→連結→オーバーレイ(PTSシフト)→字幕(最後)。--previewで720p高速プレビュー。--build-subtitlesでマスターSRTをインライン生成。grade.py <in> -o <out>— ffmpegフィルターチェーングレード。プリセット+--filter '<raw>'でカスタム。
アニメーションについては、Bash で <edit>/animations/slot_<id>/ を作成し、Agent ツールを介してサブエージェントを起動してください。
プロセス
-
インベントリ。 すべてのソースに対して
ffprobeを実行。ディレクトリに対してtranscribe_batch.py。pack_transcripts.pyでtakes_packed.mdを生成。最初の視覚的な印象を得るために、1つまたは2つのtimeline_viewをサンプリングします。 -
問題の事前スキャン。
takes_packed.mdを一度ざっと見て、言葉の滑り、明らかな言い間違い、避けるべき表現をメモします。プレーンなリストにして、編集者ブリーフに渡します。 -
会話。 見たものを平易な英語で説明します。素材に基づいて質問をします。収集する情報:コンテンツタイプ、目標の長さ/アスペクト、美的/ブランドの方向性、ペース感、絶対に残す瞬間、絶対にカットする瞬間、アニメーションとグレードの好み、字幕の必要性。固定のチェックリストは使わないでください — 適切な質問は毎回異なります。
-
戦略を提案。 4~8文:構成、テイクの選択、カットの方向性、アニメーション計画、グレードの方向性、字幕スタイル、長さの見積もり。確認を待ちます。
-
実行。 エディターサブエージェントのブリーフを介して
edl.jsonを生成。曖昧な瞬間にはtimeline_viewで掘り下げます。アニメーションは並列サブエージェントで構築します。セグメントごとにグレードを適用します。render.pyで合成します。 -
プレビュー。
render.py --preview。 -
自己評価(ユーザーに見せる前)。 すべてのカット境界(±1.5秒ウィンドウ)で、レンダリングされた出力(ソースではない)に対して
timeline_viewを実行します。各画像で以下をチェックします。- カット部分での視覚的な不連続性/フラッシュ/ジャンプ
- 境界での波形スパイク(30msフェードをすり抜けたオーディオポップ)
- 字幕がオーバーレイの後ろに隠れていないか(ルール1違反)
- オーバーレイの位置ずれや誤ったフレーム表示(ルール4違反)
また、最初の2秒、最後の2秒、中間の2~3ポイントをサンプリングして、グレードの一貫性、字幕の読みやすさ、全体的なまとまりをチェックします。出力に対して
ffprobeを実行し、継続時間がEDLの期待値と一致することを確認します。何か問題があれば:修正→再レンダリング→再評価。自己評価は最大3回まで — 3回経過しても問題が残る場合は、無限ループせずにユーザーに報告します。自己評価が合格した場合のみ、プレビューを提示します。
-
反復+永続化。 自然言語でのフィードバック、再計画、再レンダリング。決して再文字起こしはしません。確認後に最終レンダリング。
project.mdに追記します。
カットの技術(技法)
- 音声優先。 単語境界と無音ギャップからカット候補を生成します。
- ピークを保持する。 笑い、決めゼリフ、強調のビート。パンチラインを超えてリアクションを含めるように拡張します — 笑いそのものがビートです。
- 話者の交代には、発話間の間隔が有効です。一般的な値:400~600ms。テンポの速いものではより短く、シネマティックなものではより長く。センスの問題です。
- オーディオイベントをシグナルとして。
(笑い)、(ため息)、(拍手)はビートを示します。それらを超えて拡張します。 - 無音ギャップはカット候補。 400ms以上の無音は通常、最もクリーンです。150~400msのフレーズ境界は視覚的なチェックとともに使用可能です。150ms未満は危険です(フレーズ途中)。
- カットパディングの例(このスキルに付属のローンチ動画):最初の保持単語の前に50ms、最後の単語の後に80ms。モンタージュのエネルギーにはより狭く、ドキュメンタリーにはより広く。30~200msの作業ウィンドウ内に収めてください(ハードルール7)。
- 音声と映像を独立して推論しない。 すべてのカットは両方のトラックで機能しなければなりません。
圧縮文字起こし(主要な読み取りビュー)
pack_transcripts.py はすべての transcripts/*.json を読み取り、各テイクがフレーズレベルの行のリストであり、各行に [開始-終了] 時間範囲がプレフィックスとして付いた1つのMarkdownファイルを生成します。フレーズは0.5秒以上の無音または話者変更で分割されます。これはエディターサブエージェントがカットを選択するために読むアーティファクトであり、生のJSONの1/10のトークンでテキストのみから単語境界の精度を提供します。
行の例:
## C0103 (duration: 43.0s, 8 phrases)
[002.52-005.36] S0 Webエージェントが行うことの90%は完全に無駄です。
[006.08-006.74] S0 私たちはこれを修正しました。
エディターサブエージェントブリーフ(マルチテイク選択用)
タスクが「多くのクリップから各ビートの最良のテイクを選択する」場合、以下のようなブリーフを持つ専用のサブエージェントを起動します。構造は重要です。ピッチシェイプの例は必須ではありません。
あなたは<タイプ>の動画を編集しています。各ビートの最良のテイクを選択し、ソースクリップの順序ではなく、ビートごとに時系列で組み立ててください。
入力:
- takes_packed.md(すべてのテイクの時間注釈付きフレーズレベル文字起こし)
- プロダクト/ナラティブコンテキスト:<ユーザーからの2文>
- 話者:<名前、役割、話し方スタイルのメモ>
- 期待される構成:<アーキタイプを選択するか、発明する>
- 避けるべき言葉の滑り:<事前スキャンパスからのリスト>
- 目標実行時間:<秒>
一般的な構造的アーキタイプ(選択、適応、または発明):
- テックローンチ/デモ: フック → 問題 → 解決策 → メリット → 例 → CTA
- チュートリアル: イントロ → セットアップ → 手順 → 落とし穴 → まとめ
- インタビュー: (質問 → 回答 → フォローアップ) 繰り返し
- 旅行/イベント: 到着 → ハイライト → 静かな瞬間 → 出発
- ドキュメンタリー: テーゼ → 証拠 → 反論 → 結論
- 音楽/パフォーマンス: イントロ → ヴァース → コーラス → ブリッジ → アウトロ
- または独自に発明。
ルール:
- 開始/終了時刻は文字起こしの単語境界に合わせること。
- カット境界にパディングを追加(作業ウィンドウ30~200ms)。
- カット対象として400ms以上の無音を優先。
- 避けられない滑りは、より良いテイクが存在しない場合に保持する。"reason"にその旨を記録。
- 予算を超えた場合は、ビートを削除するか末尾をトリミングして修正する。合計を報告し、自己修正する。
出力(JSON配列、散文なし):
[{"source": "C0103", "start": 2.42, "end": 6.85, "beat": "フック",
"quote": "...", "reason": "..."}, ...]
最終的なEDLと1行の合計実行時間チェックを返してください。
カラーグレード(リクエスト時)
あなたの仕事は画像について推論することであり、プリセットを適用することではありません。(timeline_view を介して)フレームを見て、何が問題かを判断し、1つ調整し、再度確認します。
メンタルモデルはASC CDLです。チャンネルごと:out = (in * slope + offset) ** power、次にグローバル彩度。slope → ハイライト、offset → シャドウ、power → ミッドトーン。
フィルターチェーンの例(grade.py --list-presets で確認。これらを出発点として使用するか、独自に組み合わせてください):
warm_cinematic— レトロ/テクニカル、微妙なティール/オーランスプリット、彩度低め。実際のローンチ動画で使用されました。トーキングヘッドに安全です。neutral_punch— 最小限の補正:コントラスト強調+緩やかなSカーブ。色相シフトなし。none— そのままコピー。ユーザーから依頼がない場合のデフォルト。
ポートレート、ネイチャー、プロダクト、ミュージックビデオ、ドキュメンタリーなど、その他のものについては、独自のチェーンを発明してください。grade.py --filter '<raw ffmpeg>' は任意のフィルター文字列を受け入れます。
ハードルール:抽出時にセグメントごとに適用します(連結後に適用すると2回エンコードされます)。肌色をテストせずに積極的に適用しないでください。
字幕(リクエスト時)
字幕には、考慮に値する3つの側面があります:チャンキング(1行あたり1/2/3/文章)、大文字小文字(全て大文字/タイトルケース/自然)、配置(下端からのマージン)。適切な組み合わせはコンテンツによって異なります。
動作スタイル — 選択、適応、または発明:
classic— 1行、自然な大文字小文字、下端から8%のマージン。汎用。caption— 1~2行、自然な大文字小文字、下端から5%のマージン。トーキングヘッドに適しています。karaoke— 単語単位、自然な大文字小文字、下端から2%のマージン。音楽/パフォーマンスに適しています。cinematic— 1~2行、タイトルケース、下端から12%のマージン。映画的な感触。
ハードルール:ルール1(字幕は最後に適用)、ルール5(出力タイムラインオフセット)に従ってください。また、シーン内の既存のテキストグラフィックスとの衝突を避けるために、配置を調整してください。
このスキルの helpers/build_subtitles.py は、master.srt を生成する際にこれらのスタイルを実装しています。
このドキュメントは SKILL.md です。freecut スキルの完全なリファレンスとして機能します。