clipwise: 長時間動画 → 縦型ショート
すべてローカルで実行されます(CPUでも問題ありません。CUDAがあれば文字起こしに使用します)。
SKILL_DIR はこのファイルが置かれているフォルダを指します。すべてのコマンドは
python3 SKILL_DIR/scripts/run.py ... で実行します。スクリプトは自身で clipwise のvenvに切り替えます。
ジョブは ~/clipwise-work/<job>/($CLIPWISE_WORK)または --workdir DIR に書き込まれます。
0. セットアップ確認(セッションごとに1回)
python3 SKILL_DIR/scripts/run.py check
最後に ready と表示される必要があります。もし表示されない場合は、clipwise に一度だけセットアップが必要であること(約 2GB: Pythonパッケージ + Whisperモデル)をユーザーに伝え、SKILL_DIR/setup.sh を読むように促し、ユーザーが同意したら bash SKILL_DIR/setup.sh を実行します。ffmpeg または Python 3.10+ が不足している場合、setup.sh はOSに応じたインストールコマンドを表示します。ユーザーに確認せずにシステムパッケージをインストールしないでください。
ワークフロー
- 準備(取得 + 文字起こし、1コマンド):
ジョブフォルダに出力:python3 SKILL_DIR/scripts/run.py prep "<パスまたはリンク>" --job <名前> [--start S --max-seconds N] [--cookies cookies.txt] [--model large-v3-turbo] [--language xx]source.mp4(最初のビデオ+オーディオストリーム、SDR、リエンコード時はCFR 30)、probe.json、transcript.txt(セグメントごとに[開始-終了] (wN) テキストの行、ソース秒)、transcript.json、words.tsv。長い動画の場合は--start/--max-secondsを使用してクリップに適した部分を指定します。文字起こしはCPUで実時間の約0.6~1倍です。 - 自分で瞬間を選ぶ。
transcript.txt(および先頭の# WARNING行があればそれも)をSKILL_DIR/references/viral-rubric.mdとともに読みます。<job>/picks.jsonを作成します。各選択は10~50秒で、フックを先頭に、きれいなペイオフで終わります。数は以下のルールを参照してください。 - レンダリング前に承認を得る。 選択ごとに1行表示: タイムスタンプ、フック、タイトル、なぜ選んだかの1行。小さいCPUではクリップあたり約1~2分かかります。手動でキャプションテキストを書いた場合(非英語やコードミックス音声)、それらの行も表示します。
- レンダリング:
python3 SKILL_DIR/scripts/run.py render --job <名前> [--fast] [--only 2] [--music bed.mp3]<job>/out/に選択ごとに:clip_<id>.mp4、clip_<id>.txt(タイトル、説明、ピン留めコメント、ハッシュタグ、理由)、clip_<id>.json(プローブ値、レイアウト、顔カバレッジ、効果音、タイミング)、clip_<id>_cutmap.json、clip_<id>_sheet.png。--fast= プレビュー品質。 - すべての
clip_<id>_sheet.pngを 画像/ビジョンツールで確認します(10フレーム。赤線 = y 1620、その下はプラットフォームUI)。確認項目: 顔がフレーム内にあるか、キャプションが読めるか、キャプションが顔にかかっていないか、赤線の下に重要なものがないか、色が薄くなっていないか。問題があれば修正し(選択、キャプションオーバーライド、--layout、--font-size)、--only <id>で再レンダリングします。 - MP4パスと
.txtの内容を納品する。run.py clean --job <名前>(source.mp4とtmpディレクトリを削除し、out/を保持)を提案します。
動画あたりのショート数
-
ユーザーが数を指定した場合(「<リンク>から5本のショートを作って」): 指定された数だけ正確に作成します。動画にその数だけ強い瞬間がない場合は、レンダリング前にその旨を伝え、正直な数を提案します(「チェックリストを通過する瞬間は3つだけ見つかりました。残りの2つは弱くなります」)。
-
数が指定されなかった場合: ソース(または文字起こしした範囲)の長さに応じてスケーリングします:
ソースの長さ ショート数 5分未満 1-2 5-15分 3-5 15-45分 5-8 45分以上(ポッドキャスト、トーク) 8-15 -
ルーブリックチェックリストを通過した瞬間のみカウントします。数を合わせるために弱いクリップを追加しないでください。
picks.json(最小)
[{"id": "1", "start": 65.5, "end": 110.3, "title": "すべての洪水は気候変動が原因なのか?",
"hook_start": 74.85, "hook_end": 80.1, "payoff_start": 102.0,
"why": "予想外の主張で始まり、最後に解決する。", "comment_bait": "知ってましたか?",
"description": "...", "hashtags": ["#shorts", "#climate"],
"caption_overrides": [{"w": 219, "text": ""}, {"start": 90.1, "end": 92.4, "text": "ここに正確な言葉"}]}]
必須: id、start、end(ソース秒)。hook_start/hook_end は2~3秒の行を先頭に移動します("hook_mode": "repeat" は本文にも残します)。payoff_start は低いサウンド(thud)を配置します。caption_overrides: {"w": N, "text": ""} は単語Nを編集/削除します(transcript.txtの (wN)、words.tsvの i)。{"start", "end", "text"} はその範囲のすべての単語を置き換えます。完全なスキーマとスコアリング: references/viral-rubric.md。
レンダリングフラグ
| フラグ | 効果 |
|---|---|
--fast | x264 ultrafast CRF 24、4 fpsの顔サンプリング(プレビュー)。デフォルト: preset faster、CRF 20 |
--only ID | 1つの選択をレンダリング(繰り返し可能) |
| `--layout auto | crop |
--music FILE | ユーザー提供のBGM、音声より約17 LU下、サイドチェーン圧縮でダック。--music-db 20 = より控えめ |
--sfx-dir DIR | 合成効果音の代わりに独自の whoosh_fast、whoosh_soft、thud_low、pop、tick(.wav/.mp3/.flac/.ogg)を使用 |
--no-sfx、--no-silence-cut | それらをオフにする |
--font "Lato Black"、--font-size 84、`--highlight yellow | green、--no-upper` |
--preset、--crf、--keep-tmp | エンコーダーオーバーライド。デバッグ用に音声/ミックスwavと captions.ass を保持 |
環境変数: CLIPWISE_HOME(デフォルト ~/.clipwise)、CLIPWISE_VENV、CLIPWISE_WORK、
CLIPWISE_MODEL(デフォルト large-v3-turbo)、CLIPWISE_DEVICE(auto|cpu|cuda)。
選択ごとのレンダリング内容
フックを先頭に移動、0.35秒以上の無音をカット(しきい値はクリップ自身の音声/ノイズレベルから取得)、残った部分を30fpsのグリッドにスナップしてオーディオサンプルとフレームを一致させます。YuNetを使用した顔追跡はカット後に生き残ったフレームで行われます。支配的な顔、スティッキー(新しい顔は1.2秒間1.6倍大きくならないと引き継がない)、デッドゾーン付きのスムーズなカメラ、カット時のみスナップ。2~4秒ごとに1.0/1.12倍のパンチインズーム。単語単位のASSキャプション(最大4単語、アクティブな単語を強調表示)は顎の下、y 1620の上に配置されます。音声クリーンアップ、合成効果音、オプションのダック音楽、2パスラウドノルムで-14 LUFS / -1.5 dBTP。H.264 + AAC 48 kHz、1080x1920、30 fps。最終的なA/Vストリームの長さがアサートされます。
計測タイミング(2コアCPU、GPUなし)
| ステップ | 計測値 |
|---|---|
| 取得: 85 MB 1080p VP9 Webダウンロード + 3分間のリエンコードをH.264に | 合計7.7分(ダウンロードが支配的、約5分) |
| 取得: 20秒 10ビットHDR iPhoneクリップ(トーンマップ+CFR) | 45秒(HDRは長さの約2.3倍のコスト) |
| large-v3-turboで文字起こし、3分の英語 | ASR 110秒(実時間の0.61倍)+モデル読み込み19秒 |
| デフォルトレンダリング、40.6秒のクリップ | 85秒 |
--fast レンダリング、26.4秒のクリップ / 17.1秒のパッドクリップ | 32秒 / 30秒 |
注意点
- YouTubeのボット対策(「ロボットでないことを確認するためにサインイン」): 断続的に発生し、IPに依存します。fetchが終了コード3で終了します。ユーザーに
--cookies cookies.txt(ブラウザからエクスポート)またはファイル自体、DriveやDropboxのリンクを提供するよう依頼してください。yt-dlpのプレイヤークライアントやプロキシをループしないでください。プライベートDriveリンクは終了コード2で終了します。「リンクを知っている全員」に共有するか、ローカルファイルを提供するよう依頼してください。 - A/V同期は絶対ルールです。 すべての出力のオーディオとビデオストリームの長さは0.1秒以内で一致する必要があります(レンダリングがアサートします)。非ゼロ開始でのストリームコピーや
aselectによるオーディオカットは絶対に行わず、スクリプトを使用してください。 - ASRレシピは固定: 最初にオーディオをノーマライズし、言語を自動検出します。VADなし、
initial_promptなし(文字起こしに漏れ出します)。large-v3-turboを維持してください。smallはアクセントやコードミックス音声でループしたり幻覚を起こします(文字起こしがループについて警告します)。 - 非英語音声は翻訳されて返されることがあります。 非ラテン文字で書かれる多くの言語(およびコードミックス音声)では、Whisperは英語を返します。その場合、文字起こしはタイミングと意味のガイドとしてのみ使用します。
caption_overridesの{"start", "end", "text"}スパンを使用して、話者の言語と文字でキャプション行を書き、レンダリング前にユーザーに表示します。タイトルとハッシュタグも話者の言語に従います。 - キャプション: 決して顔にかぶせず、下部の約300px(プラットフォームUI)より上に配置します。シートで競合が発生した場合は、選択を短くするか、
--layout padを使用するか、--font-sizeを小さくします。 - トラッカーは最大の顔を追跡し、話者ではありません。 ワイドショットで2人が話している場合は、
--layout padを使用するか、1人が話す区間を選択します。 - アップスケーリング: 1080p 16:9のソースは608x1080にクロップされ1.8倍に拡大されます。720pソースは2.7倍に拡大され、画質が粗くなります。1080p以上のダウンロードを推奨します。
- 小さなCPU: 2つのエンコード、または文字起こしとエンコードを同時に実行しないでください。レンダリングは1つずつ順番に実行します(run.pyがすでにそのように動作します)。