ffmpeg-skill について
ffmpeg-skillは、再現性と検証を重視してメディアを扱うエージェント向けの動画・音声編集スキルです。編集、測定、書き出し、出力確認を行う42個のスクリプトを備え、入力の調査から結果検証までの手順を定めています。
主な機能
- 01メディア処理用の42個のスクリプト
- 02動画・音声の編集
- 03ドライランと再利用可能なプラン
- 04出力の確認と検証
- 05目視確認用のプレビュー画像
活用シーン
- 01動画クリップのカットと結合
- 02HDR映像のSDR変換
- 03指定プラットフォーム向けの書き出し
- 04要件に沿った出力ファイルの確認
MCP 対応
スクリプトをMCPツールとして公開します。既定ではtools/listに12個が表示され、FFMPEG_SKILL_MCP_FULL=1を設定すると42個すべてを有効にできます。追加のツールはtools/callから名前で呼び出せます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kajisho5/ ffmpeg-skill --skill ffmpeg-skillインストール後、Claude Code で/ffmpeg-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.npmignore.gitignoreCONTRIBUTING.mdCHANGELOG.mdLICENSE.claude-plugin/plugin.json.claude/skills/ci-pipeline-synthesizer/assets/github-actions-nodejs.ymlgithub-actions-rust.ymlgithub-actions-python.ymlgithub-actions-go.yml.claude/skills/code-review/references/review-checklist.mdresult-honesty.mdsurfaces.md.github/FUNDING.ymlpull_request_template.mddependabot.ymlrelease-drafter.yml.github/ISSUE_TEMPLATE/bug_report.mdconfig.ymlfeature_request.md.github/scripts/bump_roadmap_md.pyresolve_version.pybump_contract_md.py.github/workflows/codeql.ymldependabot-auto-merge.ymlrelease.ymlci.ymlrelease-drafter.ymldemos/CI.mdbuild.py詳細
ffmpeg-skill
スクリプトはこのファイルと同じ場所にある scripts/ に保存されています。python3 <skill-dir>/scripts/<name>.py で実行してください。納品用テンプレートは templates/ にあります。このファイルだけで作業できます。以下の表でリクエストに応じたスクリプトを確認でき、実行するスクリプトの --help を使えば、すべてのフラグを最も手軽に確認できます。リファレンスファイルはこのファイルと同じくらいの情報量があります。必要な疑問がある場合にのみ開いてください。references/scripts.md(全42スクリプトのすべてのフラグ)、references/devices.md(iPhone HDR、GoPro、DJI、画面録画、Zoom)、references/gotchas.md(末尾にある一行ルールの詳細版)があります。MCP:デフォルトでは tools/list にコアの12個のみが表示されます。この表に記載されている残りの30個も、contract --json の説明に従って、名前を指定すれば tools/call で呼び出せます。42個すべてを表示するには FFMPEG_SKILL_MCP_FULL=1 を設定してください。
すべてのスクリプトで共通のフラグ:--dry-run、--json(出力パス、出力のプローブ結果、実行したコマンドを出力)、--json-brief(ステータス/出力/検証結果と summary を出力。書き込みを行う手順ではこちらを推奨)、--fast(プレビュー品質)、--progress、--timeout SECONDS(kind: timeout、デフォルトは1800)、--overwrite(手順7)、--plan FILE(ドライランをプランとして保存し、後から render.py FILE で実行します。入力に変更がある場合は実行を拒否します)。再エンコードツールでは、--codec h264|hevc|av1|prores と --quality N も使用できます。未指定の場合、SDRではx264、HDRではx265 Main10が使われます。prores には -o NAME.mov が必要です。h264 はHDRを拒否します(先に color.py --to-sdr を実行してください)。
書き込みツールは --dry-run の場合、何も実行しません。計測ツール(probe、check、sync、multicam、scenes、cropdetect、report、silence、loudness、stabilize)は、アーティファクトやサイドファイル(--edl、--sheet、生成される .ass)の作成を省略したうえで、ffmpeg/ffprobeを実行する場合があります。verify はこのフラグを無視します。ツールごとの contract --json の dry_run を参照してください。
ワークフロー(この順序で)
- 環境の確認は、失敗した場合のみ。
doctorでジョブを開始してはいけません。マシンに問題がある場合、kind: missing_toolまたはフィルター/エンコーダー名を含む ffmpeg エラーが発生します。そのような失敗の後、またはマシンで何ができるかを尋ねられた場合に、python3 <skill-dir>/scripts/_contract.py doctor(またはnpx ffmpeg-skill doctor)を実行し、ok/usableを読み取って、不足している機能を報告します。contract --jsonのツールスキーマは、計画用エージェント向けであり、このワークフロー向けではありません。 - 計画に必要な情報を調べます。 計画対象となる各入力、およびファイルについてユーザーから尋ねられた場合は、
probe.pyを実行します。確認する項目は、長さ、fps、解像度、コーデック、チャンネル、variable_frame_rate_suspectedです。編集のたびに個別のプローブを実行する必要はありません。各書き込みツールの--jsonには、入力情報と出力のプローブ結果が含まれます。推測ではなく、実際の数値に基づいて計画します。 - 可能な限りロスレスを優先します。 再エンコードなしで要望を満たせる場合(キーフレームでの単純なカット、リマックス、音声のみの変更など)は、再エンコードしません。
cut.pyとloudness.pyは、デフォルトで動画をストリームコピーします。cut.pyの--accurateは、フレーム単位で正確なカットが必要な場合に限って使います。 --dry-run --jsonで計画してから実行します。 計画に含める数値については、ドライランの要約行ではなく--jsonを信頼してください(そこに表示される寸法はプレースホルダーの場合があります)。長時間のエンコードの前に使い、事実を報告します。--fastはプレビュー品質です。--progressは標準エラー出力にパーセンテージ/残り時間を表示します。ユーザーが置き換えを指示していない限り、このジョブで作成していないファイルを-oの出力先に指定してはいけません。その場合に限り、--overwriteを指定します。- 適切な順序で処理をつなぎます。 編集を伴わない納品依頼には、手作業で処理をつなぐのではなく、テンプレートを一度実行します(
render.py --template NAME INPUT)。それ以外の場合は、色(HDR→SDR/LUT)→ カット → 結合 → 無音 → フィット → 字幕/オーバーレイ → 同期 → 音声 → ラウドネス → 書き出し、の順にします。字幕のサイズを最終フレームに合わせるため、字幕を入れる前にフレームを変更します。再エンコードはできるだけ少なくし、中間ファイルには CRF 18 を使い、最後にexport.pyを実行します。3 ステップ以上の場合は、project.json を使ってrender.pyを実行します。 - 納品物を確認します。 報告する前に、指定された納品先に対して
check.py OUTPUT --platform Xを実行します(テンプレートの実行では、すでに確認されています)。形式に関する行(コーデック、ピクセル形式、サイズ、トゥルーピーク、色タグ、VFR)は安全に修正できます。判断が必要な行は内容を変えます。長さ(カットで素材が失われます)、アスペクト比(クロップで端が失われます)、fps(動きが失われます)、ラウドネス(環境音はブーストすべきではありません)は、依頼から対応方針が明らかな場合に限って修正します。それ以外の場合は、選択内容とその代償を伝えます。WARN を報告し、追いかけて修正しないでください。 - 出力を検証します。 書き込みツールの
--json/--json-briefに含まれるプローブ結果、またはprobe.pyで、長さ、解像度、fps、音声が要望どおりであることを確認し、その数値を報告します(「final.mp4:59.98 秒、1080x1920、30 fps、AAC ステレオ」)。スクリプトが終了コード 0 で終了し、出力が想定どおりにプローブされて初めて、ステップが完了します。終了コードが 0 以外、ファイルが存在しない、ファイルが空、またはプローブ結果が要望と矛盾する場合は、スクリプトのエラーメッセージとともに失敗を報告します。 - ユーザーのオリジナルを保持します。 ソースを上書きしてはいけません。入力ファイルの隣、または指定された場所に新しいファイルを書き込みます。出力先に既存ファイルがある場合は拒否されます(
kind: input)。置き換えを許可する方法は--overwriteのみです。 - 映像を目で確認します。 映像に変更を加えた場合(字幕、オーバーレイ、グラフィック、クロップ/パディング、リサイズ、色、トランジション、
join.pyによるクリップの先頭クリップのフレームへのスケーリング、color.py --to-sdr)は、look.py OUTPUT --tiles 3x2(1 フレームの場合は--at T)を実行し、PNG を確認します(クリップ全体のレイアウトでは 4x3 を使用)。Look:にその PNG が記載されるまで完了ではありません。プローブでは、顔に字幕が重なっているかどうかは分かりません。音声のみの場合はLook: not neededとします。確認項目は、ステップ 5 のcheck.pyの行と同様に分けます。- 機械的な確認(このスキルが検証して報告すること): 指定されたテキスト/ロゴが指定位置にあること、指定タイムスタンプに字幕が表示されること、寸法が偶数であること。
fit.py --fit padによるレターボックスは、そのモードでの正しい結果であり、問題として報告してはいけません。 - 判断が必要な確認(報告はするが、黙って合否を決めないこと): 被写体や顔が切れていないか、顔にテキストが重なっていないか、色が白っぽく見えないか、トランジションの位置が適切か。これらは被写体が「何であるか」の判断が必要であり、呼び出し元のエージェントが決めることです。見たことを一文で伝え、判断はエージェントに委ねます。
ビジョン機能がない場合は、
Look: PATH (pixels not inspected; agent has no image view)と記載します。実際には確認していない画像を確認したと主張してはいけません。また、利用できない機能を待つために処理を止めてはいけません。
- 機械的な確認(このスキルが検証して報告すること): 指定されたテキスト/ロゴが指定位置にあること、指定タイムスタンプに字幕が表示されること、寸法が偶数であること。
実行する前に:何を尋ね、何を前提とするか
回答によって出力が大きく変わり、依頼からも答えが推測できない場合に限り、短い質問をしてください。複数の項目が同時に未確定の場合(「SNS向けにして」という曖昧な依頼では、投稿先、アスペクト比、長さ、字幕が未確定です)、一度に一つずつ質問するのではなく、デフォルト設定をまとめて提示し、ユーザーがどの項目も変更できるようにしてください(「Reels:9:16の余白付き、60秒、-14 LUFS、字幕なし — これでよいですか?」)。質問は一つ、回答も一つで、その後に実行します。probe.py で確認できることは尋ねないでください。
- 投稿先によってアスペクト比、長さの上限、ラウドネス、コーデックが決まります。「Reels向け」であれば、この4項目すべてが決まり、テンプレートも特定できます。投稿先が指定されておらず、単純なカットや字幕の依頼であれば、ソースの形式を維持し、その旨を伝えてください。「書き出し」「投稿」「納品」と言われた場合は、どこ向けかを尋ねてください。
- 長さ(「60秒にして」など)について、方法の指定がない場合、変更が1.5倍以内であれば速度を上げ、それ以外はトリミングし、どちらにしたかを伝えてください。トリミングで言葉が失われるトーク動画で、変更幅が大きい場合は尋ねてください。
- 字幕にテキストソースの指定がない場合、ローカルに whisper があれば
--transcribeを使い、なければテキストまたはタイムコード付きファイルを求めてください。会話を捏造してはいけません。 - フォントとブランド:ブランド、色、「自社のフォント」について言及された場合は、一度だけ
brand.jsonを求めるか作成し、再利用してください。 - CJK/非ラテン文字のテキスト:ツールにスクリプトに応じたフォントを選ばせてください(
--fontを指定すると無効になります)。漢字のみのテキストには--lang ja|koを使ってください。doctor --jsonの.fonts.scriptsで、ここで表示できる文字を確認できます。文字化けはジョブの失敗です。 --fit cropのクロップ位置:デフォルトは中央です。ただし、依頼やソースに中心から外れた被写体が指定されている場合(「商品を右側に残して」や、シート上で明らかに中心から外れている人物など)は、中央と決めつけずに--crop-x/--crop-yを使ってください(0=左/上、1=右/下)。または、どちらの端を残すか尋ねてください。- それ以外の項目(トランジションの種類、字幕のスタイルなど)は、一般的なデフォルトを選び、選択した内容を伝え、別案も1行で提示してください。
このスキルが判断することと、判断しないこと
このスキルはファイルの切り取り、結合、計測、同期、書き出し、チェックを行います。編集を実行しますが、編集内容は判断しません。何を誰が担当するかは次のとおりです。
- どのカットが適切か、または納品物を承認できるか — このスキルは計測して報告します(
check.pyの PASS/WARN/FAIL、cut.pyの長さの誤差)。納品するかどうかは、ユーザーまたは制作エージェントが判断します。 - ハイライトとして何が面白いか —
scenes.py --highlightsは計測可能な代替指標(音声のエネルギー、長さ)に基づいて順位付けします。候補を示すものであり、最終判断ではありません。 - サムネイルやカバーの構成 — 計測ではなく、デザイン上の判断です。
- 動画の内容を理解すること — ここでの映像解析は
look.pyのコンタクトシートのみです。これは呼び出し元のエージェントが目視するためのものであり、このスキルが解釈するためのものではありません。 - 見栄えの良し悪しを判断すること — 「この LUT を適用する」「露出を +0.3 段補正する」(
color.py)は機械的な処理です。「このシーンを映画のように見える色調にする」ことは、パラメーターを決めてからcolor.pyを呼び出すカラーグレーディングスキル(color-grading-skill)の担当です。 - キャプションの文言 — キューテキストは記載どおりに焼き込みます。フレームに収まらない場合は、文字サイズを小さくするか、
--max-linesを指定するか、ユーザー自身に編集してもらいます。「収まるようにして」と頼まれても、書き換えたり、短くしたり、言い換えたりしてはいけません。その旨を伝え、小さい文字サイズで--max-lines 1を指定する方法を提案します。 - 指定されていない被写体や領域を選ぶこと — 範囲が分かっていれば「x=200,y=0 にクロップする」は機械的な処理です。「話者がフレーム内に残るようにクロップする」には、話者が誰かを判断する必要があり、これは
look.pyのシートを見たうえで呼び出し元のエージェントが判断することです。
このスキルが担当するのは、同じ入力に同じ明示的なパラメーターを指定すれば、常に同じ検証可能な出力が得られる処理です。好み、理解、見た目や音の良し悪しに依存することは、そうした判断を行う人の担当です。
42 個のスクリプトのどれにもない FFmpeg の機能が必要な場合は、その旨を伝え、最も近い組み込みオプションを挙げてください。scripts/*.py の外で ffmpeg/ffprobe を直接呼び出す方法を推測してはいけません。それでは、このスキルが保証するすべてのことを回避することになるため、スクリプトのフラグで対応できない場合の代替手段としても使ってはいけません。
リクエスト → スクリプト
この表と doctor --json の tools リストが、利用可能な機能の正確な情報源です。どちらかで確認したスクリプトだけを挙げてください(doctor.py、trim.py、subtitle.py はありません)。
タイムスタンプ用フラグ(--start、--end、--at、--from、--duration、--offset、およびキューとチャプターファイル内の時刻)には、秒、mm:ss(.fff)、hh:mm:ss(.fff)、または @fps 付き SMPTE 形式の hh:mm:ss:ff(00:01:02:[email protected])を指定します。NLE のキューシートはそのまま貼り付けてください。長さ用フラグ(--min-silence、--margin、--fade)には、秒数のみを指定します。
| ユーザーの指示 | 実行内容 |
|---|---|
| 「1:20から2:05までカットして」「最初の10秒をトリミングして」 | cut.py input.mp4 --start 1:20 --end 2:05 |
| 「この部分だけ残して」「中間を削除して」 | cut.py input.mp4 --segments 0-1:00,1:30-2:00 |
| 「ちょうど60秒にして」 | fit.py input.mp4 --duration 60(速度)または --method trim |
| 「カットしてHEVC/AV1/ProResにして」(出力コーデックの指定あり) | cut.py input.mp4 --start 0:10 --end 0:40 --codec hevc(再エンコードするツールでは --codec/--quality を指定できます。ProResでは -o NAME.mov が必要です) |
| 「無音部分をカットして」「ジャンプカットして」 | silence.py input.mp4 [--threshold -40 --min-silence 0.8] |
| 「えーと、あのーをカットして」「フィラーワードを削除して」 | silence.py input.mp4 --filler --words words.json(実測した単語のタイミングを使用します。--transcribe で作成できます) |
| 「文の途中ではカットせず、本当の無音部分だけカットして」 | silence.py input.mp4 --speech-aware — 文の途中にある --min-silence 未満の息継ぎは残し、文の切れ目にある無音部分だけをカットします。--filler と組み合わせて1つのリストにできます |
| 「この1時間の映像から60秒のハイライトを作って」 | scenes.py long.mp4 --highlights 6 --target 60 --edl picks.txt → cut.py --segments |
| 「ビートに合わせてカットして」「音楽に合わせて編集して」 | scenes.py track.mp4 --beats --json > beats.json を実行してから、cut.py input.mp4 --segments ... --snap beats --snap-source beats.json を実行します(--snap-source で実測したグリッドを引き継ぎます) |
| 「ここを速く、あそこをスローモーションにして」(区間が既知) | speedramp.py action.mp4 --segment 0-3:1.0 --segment 3-4:0.25 --segment 4-8:2.0 |
| 「このフレームを止めて」「最後のフレームをフリーズして」 | freeze.py clip.mp4 --hold 2 |
| 「滑らかなスローモーションにして」「半分の速度でも滑らかに」 | fit.py input.mp4 --duration 2x --smooth interpolate(スロー)または --smooth blend |
| 「このクリップを逆再生して」 | reverse.py input.mp4 |
| 「このクリップをループして30秒にして」 | loop.py bg_loop.mp4 --duration 30 |
| 「縦型/9:16/正方形にして」 | fit.py input.mp4 --aspect 9:16 --fit pad(または --fit crop。ぼかした帯を付ける場合は --pad-fill blur) |
| 「高さ/幅を指定してリサイズして」 | fit.py input.mp4 --height 1080(または --width、厳密なフレームサイズを指定する場合は両方) |
| 「この正確な範囲でクロップして」(x/y/w/hが既知) | crop.py input.mp4 --x 100 --y 0 --width 1080 --height 1920 |
| 「黒帯の代わりにぼかした背景を付けて」 | fit.py input.mp4 --aspect 9:16 --fit blur(映像全体を残し、ぼかして暗くした映像を背景にします) |
| 「90度回転して」「反転して」 | fit.py input.mp4 --rotate 90 / fit.py input.mp4 --flip h |
| 「水平線が傾いている」(角度が既知) | straighten.py tilted.mp4 --degrees -2.5 |
| 「この360度動画を平面表示にして」(ヨー/ピッチ/視野角が既知) | sphere.py insta360.mp4 --yaw 90 --pitch 0 --h-fov 100 --v-fov 70 |
| 「この古い映像はインターレース方式です」 | deinterlace.py input.mp4 |
| 「ざらつきやノイズを除去して」 | denoise.py input.mp4 --strength medium |
| 「この顔/ナンバープレートをぼかす/モザイク処理する」(範囲が既知) | redact.py input.mp4 --x 820 --y 140 --width 240 --height 240 --mode pixelate |
| 「この手ブレした映像を安定させて」 | stabilize.py input.mp4 |
| 「黒帯があるか確認して」 | cropdetect.py input.mp4 |
| 「iPhoneのDolby Visionクリップの見た目がおかしい」 | color.py clip.mov --to-sdr または --strip-dovi(HDRは維持し、DVレイヤーを削除します) |
| 「色が薄く見える/iPhoneのHDR映像です」 | color.py input.mov --to-sdr(プローブ結果に hdr: true と表示されます) |
| 「このLUTを適用して」「S-Log映像を変換して」 | color.py input.mp4 --lut grade.cube [--lut-strength 0.7] |
| 「色のタグが間違っている」 | color.py input.mp4 --retag bt709(ストリームコピーします。コピーでタグを維持できない場合のみ再エンコードします。reencoded を参照してください) |
| 「明るくして/コントラストを強くして/ホワイトバランスを調整して」 | color.py input.mp4 --correct --exposure 0.3 --contrast 1.1 --saturation 1.05 --temperature 5600 --tint -0.05 |
| 「このSRTから字幕を追加して」「字幕を映像に焼き込んで」 | caption.py input.mp4 --srt subs.srt |
| 「この行で字幕を付けて」(時間付きテキスト) | caption.py input.mp4 --text cues.txt |
| 「字幕の表示/非表示を切り替えられるようにして」「SRTを多重化して」 | caption.py input.mp4 --srt subs.srt --mode mux。複数の言語には --srt file:lang を繰り返し指定し、2言語を超える場合は .mkv を使います |
| 「字幕が小さすぎる/Shortsで3行になっている」「文を途中で切らないで」 | caption.py は、字幕キューを分割する前に --max-lines に収まるよう文字サイズを縮小します(--fit-size off を指定すると --size を維持して分割し、--min-size で下限を設定します)。テンプレートの --max-lines(縦型では2)を維持し、文字サイズを下げてください。縮小を避けるために行数を増やすと、1行に2語が詰め込まれます。下限の文字サイズでも列幅を超える単語は、書き換えずに端で自動的に分割します(ハイフンを優先します)。JSONの broken_inside_word にその数が記録されます |
| 「文字起こしして字幕を付けて」 | caption.py input.mp4 --transcribe --animate pop --karaoke(ローカルのwhisperが必要です。ない場合は --text を使います) |
| 「単語が飛び出すTikTok風の字幕にして」 | caption.py input.mp4 --text cues.txt --animate pop --karaoke |
| 「ロゴを右上に」「ウォーターマークを追加して」 | overlay.py input.mp4 --image logo.png --position top-right --scale 200 |
| 「最初の4秒間にタイトルを表示して」 | overlay.py input.mp4 --text "Title" --position top --start 0 --end 4 --fade 0.4 |
| 「隅にウェブカメラの映像を表示して」「ピクチャー・イン・ピクチャーにして」 | overlay.py input.mp4 --video webcam.mp4 --position bottom-right --scale 480 |
| 「グリーンスクリーンを除去して」 | overlay.py bg.mp4 --video greenscreen.mp4 --chromakey 0x00ff00 |
| 「名前入りのローワーサードを追加して」「カウントダウンのイントロを作って」「プログレスバーを追加して」 | graphics.py input.mp4 --template lower-third --name "..." --title "..." --start 2 --end 8 |
| 「ステッカーを追加して」「最初の3秒にフックカードを表示して」「ミーム用のテキストを追加して」 | graphics.py input.mp4 --template sticker --text "NEW" --platform tiktok / --template hook --title "..." --duration 3 / --template meme --top "..." --bottom "..." |
| 「ブランドのフォント/色/ロゴを使って」 | caption/overlay/graphicsで --brand brand.json を指定するか、project.jsonで "brand" を指定します |
| 「ラベリアマイクの音声を同期して」「2台のカメラを合わせて」 | sync.py camera.mp4 mic.wav --replace-audio / sync.py camA.mp4 camB.mp4 --trim-second。3台目以降のレコーダーは追加の位置引数で指定します(sync.py ref.mp4 mic.wav cam2.mp4)。オフセットJSONは1つだけ指定します |
| 「音量レベルを調整して」「-14 LUFSに正規化して」 | loudness.py input.mp4(ポッドキャストには -I -16 --tp -1.5、放送には -I -23 を指定します。範囲を設定するには --lra N を指定します) |
| 「音声をきれいにして」「ヒスノイズを除去して」 | audio.py input.mp4 --voice(音声向け。--voice light|medium|strong)または --denoise |
| 「話し声の下にBGMを追加して」 | audio.py input.mp4 --music bed.mp3 --duck --fade-out 3(--effects sfx.wav は3つ目の音声レイヤーを追加し、ダッキングは適用しません。プロジェクトのレベル設定:audio.stems) |
| 「音楽のダッキングを強くして/復帰を速くして」 | --duck-amount 18 --duck-threshold -30 --duck-release 250 を追加します(--duck-attack も指定できます) |
| 「ミックスの音場が狭い」「ステレオを広げて」 | audio.py band.wav --stereo-widen 0.5(ステレオの元音源が必要です。5.1には --downmix が必要です) |
| 「5.1をステレオに変換して」 | audio.py input.mov --downmix |
| 「ナレーション音声に差し替えて」 | audio.py input.mp4 --replace narration.wav |
| 「音声を取り出して」「WAVで音声を出力して」 | audio.py input.mp4 -o input.wav(音声ファイルの拡張子を指定すると映像は出力されません。トラックを選ぶには --audio-stream 1 を指定します) |
| 「声をコンプレッションして」「ピークを抑えて」「部屋のノイズをゲート処理して」 | audio.py input.mp4 --compress --comp-threshold -20 --comp-ratio 4 / --limit --limit-ceiling -1 / --gate --gate-threshold -45 |
| 「1時間の間に音声と映像の同期がずれてくる」 | sync.py camera.mp4 recorder.wav --fix-drift --replace-audio |
| 「このポッドキャストを動画にして」「オーディオグラムを作って」 | render.py --template audiogram ep.m4a --image cover.png — 静止画またはカラープレートの上に波形を表示します。外部からの取得はありません |
| 「TikTok/Reel/Short/YouTube/X/LinkedIn/ポッドキャスト用にして」 | render.py --template tiktok|reels|shorts|youtube-shorts|youtube|x|linkedin|facebook|podcast input.mp4 [--cues cues.txt] [--title "..."] — フレーム、字幕、ラウドネス、書き出し、チェックを1つのコマンドで実行します(--list-templates、先に編集する場合は --write-project) |
| 「すべての場所に投稿して」「すべてのプラットフォーム向けに一度に編集して」 | render.py --template all input.mp4 --cues cues.txt(またはカンマ区切りのリスト)→ 配信先ごとに1ファイルと <name>_pack.md を出力します(report.py --pack でHTMLを生成します) |
| 「YouTube/Reels/X用に書き出して」「ProResマスターを作って」 | export.py input.mp4 --preset youtube|reels|tiktok|shorts|linkedin|facebook|x|prores|h265(--normalize を指定すると同じ呼び出しでラウドネス仕様に合わせます。youtube-hdr はHDRを維持し、youtube-av1 はAV1で出力します) |
| 「GIFのプレビューを作って」 | export.py input.mp4 --preset gif |
| 「軽量なプロキシ/手軽なプレビューファイルを作って」 | proxy.py input.mp4 [--width 640 --no-audio] — 納品用プリセットではありません(納品には export.py を使います) |
| 「アップロードして問題ないか確認して」 | check.py final.mp4 --platform reels |
| 「チャプター付きのポッドキャストエピソードを作って」 | loudness.py ep.wav -I -16 --tp -1.5 → metadata.py ep.m4a --chapters chapters.txt → check.py ep.m4a --platform podcast(チャプター行とチャンネル行) |
| 「実行した内容の要約を送って」 | report.py --before raw.mov --after final.mp4 --platform youtube -o report.html |
| 「この画像をクリップにして」「タイトルカードを作って」 | insert.py title.png --duration 3 |
| 「写真をゆっくりズームして」「ケン・バーンズ効果を付けて」 | insert.py photo.jpg --duration 6 --zoom in --pan right --width 1920 --height 1080 |
| 「無地/カラー背景のクリップを作って」 | background.py -o bg.mp4 --duration 3 --width 1920 --height 1080 --color 0x101010 |
| 「連番画像を動画にして」 | sequence.py --dir frames --pattern "frame_%04d.png" --fps 24 |
| 「このトラックの波形/スペクトログラム動画を作って」 | waveform.py podcast.wav -o waveform.mp4 |
| 「最初に黒画面を追加して」 | pad.py clip.mp4 --start 1.5 |
| 「0:12〜0:16を商品ショットに切り替えて」「この部分にBロールを重ねて」 | broll.py talk.mp4 --insert product.mp4 --at 12 --end 16(--insert/--at を繰り返し指定します。--audio b|mix) |
| 「チャプターを追加して」「YouTube用のチャプターマーカーを追加して」 | metadata.py episode.mp4 --chapters chapters.txt(1行につき TIME TITLE を指定します。ストリームはコピーされます。プロジェクトでは "chapters" を指定します)。--auto-chapters は実測した無音部分/シーンの切り替わりからチャプターを提案します(Chapter N) |
| 「タイトル/アーティスト/コメントを設定して」 | metadata.py episode.mp4 --title "Episode 12" --artist "Studio" |
| 「これらの動画を4x2のグリッドに並べて」 | grid.py t1.mp4 ... t8.mp4 --cols 4 --rows 2 |
| 「これらのクリップをつないで」「クロスフェードを追加して」 | join.py a.mp4 b.mp4 c.mp4 --transition fade --duration 0.5(TTS:--list parts.txt、--on-missing skip、--on-silent fail) |
| 「1つの編集に複数の変更を加えて」、3ステップ以上 | render.py --init project.json を実行し、編集してから render.py project.json を実行します |
| 「1つの段階を変更したので、残りはやり直さないで」 | render.py project.json --cache DIR — 変更のない段階は再利用されます(--from STAGE はその段階から開始します) |
| 「Premiere/Resolve/Final Cutで開いて」 | render.py project.json --export-timeline edit.fcpxml|.edl|.otio — レンダリングは行いません。not_exported を確認してください。プロジェクトがない場合は --write-project を指定します |
| 「フォルダー内のすべてのファイルに実行して」「すべてのコアを使って」 | batch.py FOLDER --recipe batch.json --jobs auto(ステップまたはレンダープロジェクトを実行します。キャッシュされます) |
| 「3台のカメラを切り替えて」 | multicam.py camA.mp4 camB.mp4 camC.mp4 --switch "0-20:0,20-40:1,40-60:2"(手動)または --switch energy(--min-shot)。--edl はカットリストです。エディター用には --write-project p.json → --export-timeline を指定します |
| 「このファイルの内容を確認して」「長さを確認して」 | probe.py input.mp4 |
| 「見た目を確認して」「字幕が読みやすいか確認して」 | look.py output.mp4 --tiles 3x2 を実行してから、PNGを表示します |
| 「どのコマンドを実行するか教えて」「まだレンダリングしないで」 | 任意のスクリプトで --dry-run を指定します |
| 「どのショットが静止/動きありか」「秒ごとの音量ピーク」「音声か音楽か」 | scenes.py input.mp4 --shots(ショットごとの静止/パン/動きと、実測したフロー)/--audio-peaks(dBFSのリスト)/--speech(音声と音楽の比率。分類ではありません)。組み合わせて使うことも、単独で使うこともできます |
| 「自分でクロップできるように、被写体がどこに動くか教えて」 | cropdetect.py input.mp4 --motion-centre — 1秒ごとの動きの重心を報告します。クロップ範囲は呼び出し元のエージェントが決定します |
| 「Log/S-Logのように見えるか」 | probe.py clip.mp4 --analyze(looks_like_log)を実行してから color.py --lut を実行します |
| 「手持ちのファイルでツールをテストして」 | verify.py ~/Footage --report verify.md |
| 「進行状況を表示して」「まずはすばやくプレビューして」 | 任意のエンコード用スクリプトで --progress および/または --fast を指定します |
| 「可変フレームレートのスマートフォン動画です」 | 追加の指定は不要です。再エンコード時にVFRから固定フレームレートに変換されます。フレームレートは fit.py --fps 30 で指定します |
音声のみのファイル
音声は第一級の入力です。probe、cut、silence、loudness、audio、sync、check --platform podcast、render --template podcast は WAV、FLAC、MP3、M4A/AAC、OGG、Opus を受け付けます。出力形式は拡張子で決まります。映像を必要とするスクリプト(fit、caption、overlay、graphics、color、export、scenes、look)は「input has no video stream」として音声を拒否します。無理に映像コンテナで包まないでください。レシピ: references/gotchas.md#audio-only-files。
レポート形式
リクエストが書かれた言語で返信してください。別の言語の字幕であっても、リクエストの言語でレポートします。ラベル(Done:、Steps:、Check:、Look:、Notes:)は英語のままにし、それ以外はすべてユーザーの言語にします。作業が短時間だったり失敗したりしても、決してぶれてはいけません。一行の「file does not exist」であっても同様です。会話の途中で切り替わった場合は、ユーザーの最新のメッセージに従います。
すべての作業を次の形で終えてください(数値は記憶ではなく --json または probe.py/check.py から取得します):
Done: final.mp4 — 59.98 s, 1080x1920, 30 fps, H.264, AAC stereo, -14.1 LUFS
Steps: cut 0:12-1:12 (lossless) -> fit 9:16 crop -> captions (pop, karaoke) -> loudness -14 -> export reels
Check: reels — all 12 checks pass (verified: true)
Look: final_sheet.png (captions inside the safe area, logo top-right)
Notes: source was VFR, conformed to 30 fps; audio was mono, made stereo
日本語のリクエストでも同じ5行です:
Done: final.mp4 — 59.98 秒、1080x1920、30 fps、H.264、AAC ステレオ、-14.1 LUFS
Steps: 0:12-1:12 をカット(無劣化)-> 9:16 にクロップ -> 字幕(ポップ、カラオケ)-> ラウドネス -14 -> Reels 書き出し
Check: reels — 12 項目すべて合格(verified: true)
Look: final_sheet.png(字幕はセーフエリア内、ロゴは右上)
Notes: 元は VFR だったので 30 fps に揃えた。音声はモノラルだったのでステレオにした
これらの5行に加え、ユーザーが判断すべきことだけを記載してください。出力の probe なしに成功を報告しないでください。実行していない修正を説明しないでください。
ステップが失敗した場合は、Done: を Failed: に置き換え、残りは正直に保ちます:
Failed: color.py --lut grade.cube exited 1 — ffmpeg: "Unable to parse LUT file" (the .cube is not a valid LUT)
Steps: probe -> color (failed); nothing written
Check: nothing to verify
Look: not needed
Notes: send a valid .cube, or say if you want the clip left as is
これらの定型行はラベルではなく文です。日本語のリクエストに対する同じレポートは
Check: 検証するものなし / Look: 不要 で終わります。
拒否も同じ形を使います。Failed: は何をなぜ拒否したかを示し、Steps: は実際に実行されたものを列挙し、Look: not needed とします。最も短い失敗でも5つのラベルすべてを含め、見出しは使いません。部分的な結果は Done: とし、不足分を Notes: に記載します。何かを提供しつつ拒否する場合は Failed: です。Done (partially): のような第三のラベルは決して使いません。失敗の error.hint を Notes: に引用してください。それは再試行に必要なフラグ変更です。
すべてのスクリプトは --json を付けると {"status": "failed", "error": {"kind": input | ffmpeg | output | missing_tool | timeout | verification | interrupted, "message": ...}} を出力し、非ゼロで終了します。メッセージは言い換えず、そのまま引用してください。
正しそうに見えても誤っていること
それぞれ1行です。該当する作業を行う場合は、リンク先の references/gotchas.md のセクションを開いてください。
- HDR(iPhone、HDR10)をSDR経路で再エンコードすると、映像が平坦になります。スクリプトはHDRを維持します。
hdr: trueは実際のPQ/HLG/DV信号を示し、bt2020_or_hdr: trueはBT.2020のSDRも示します。-> #hdr-and-colour - Log映像(S-Log/V-Log/C-Log)はSDRとしてタグ付けされるため、グレーに見えます。まず
probe.py --analyzeを実行し、次にcolor.py --lutを実行してください。-> #log-footage -c copyでカットすると、誤ったフレームや静止したフレームから始まることがあります。cut.pyは0.5秒のスナップを超えると再エンコードします。この動作を尊重してください。-> #keyframe-cuts- VFRのスマートフォン/画面録画は、再エンコード時にCFRに変換され、
cut.pyは--accurateに切り替わります。フレームレートが不規則な場合は、fit.py --fpsで選択してください。-> #variable-frame-rate - 同期/マルチカムの
confidenceが0.3未満(またはオフセットが非常に大きい)なら、信頼できない可能性があります。すべてのカメラを確認してください。これらは音声を同期するものであり、リップシンクは行いません。-> #sync-multicam-and-drift - 「ノーマライズ」した音声でもクリッピングすることがあります(トゥルーピークを確認してください)。-40 LUFS以下の環境音を、音声の目標レベルまで上げてはいけません。-> #loudness-and-ambience
- 字幕をクロップ/リサイズの前に焼き込むと画面からずれます。小さく焼き込んでから
export.pyで拡大すると、ぼやけて表示されます。-> #captions-fonts-and-text-order - 絵文字をカラーで描画するには
--emoji-assets DIR(字形ごとのPNG)が必要です。指定しない場合はモノクロで表示され、その旨が報告されます。-> #emoji - 非ラテン文字のフォントは文字体系に応じて選択されます(
graphics.pyはlibass経由でデーヴァナーガリー文字、ベンガル文字、タミル文字、タイ文字を整形しますが、drawtextではできません)。フォントがない場合、ジョブは失敗します。-> #fonts-by-script --fit cropで16:9から9:16に変換すると、横幅の70%が失われます。「60秒」は速度によるものかトリミングによるものかで結果が異なります。どちらを指すのか、その理由とともに明示してください。-> #reframing-fps-and-duration- TikTok/Reelsでは、画面下部の5分の1と右側の列が独自のUIで覆われます。テンプレートではその領域にテキストを配置しません。
look.py --safe tiktokで確認できます。-> #platform-safe-zones scenes.py --highlightsは音量(または長さ)で順位付けし、意味に基づいて選ぶことはありません。選択結果を信用する前に一覧を確認してください。-> #highlights- 再エンコードにはx264
mediumを使用します。1つのrender.pyプロジェクトで3回以上連続して処理してください。-> #chaining-and-speed