analyze-footage — 素材解析
いつ使うか(必ず発火する条件)
- ユーザーが素材フォルダや動画ファイルを渡し、「分析して」「素材を見て」「03_analysis を作って」と言ったとき
- ユーザーが素材を指して「この動画で」「この素材で」「この映像から」のように依頼し、クリップ内容の理解が必要なとき
projects/<project>/03_analysis/を初回生成するとき、または素材差し替え後に再解析するときdesign-intentやfull-pipelineから、素材理解の前提 artifact として analysis が必要なとき
前提条件
npx tsx、ffmpeg、ffprobeが使えること- 出力先
projects/<project>が決まっていること - STT を使うなら
GROQ_API_KEYかOPENAI_API_KEYを用意すること - VLM を使うなら
GEMINI_API_KEYを用意すること - 相対素材パスは repo root ではなく
--projectで渡した project directory 基準で解決されること - downstream で
select-clipsや peak ベースの判断をしたいなら--skip-peakを使わないこと
やること(ステップ)
Step 1: 素材と project を特定する
- 対象の source file 群と
--projectを確定する - 既に
01_intent/creative_brief.yamlがあるか確認する - 再解析なら既存の
03_analysis/assets.json、segments.json、gap_report.yamlを読んで stale / 欠落理由を把握する
Step 2: content-hint を自動抽出する
references/content-hint-guide.md を参照する。
優先順位:
01_intent/creative_brief.yamlにcontent_hintがあればそれをそのまま使うcontent_hintが無ければmessage.primaryを主軸にし、must_have、project.title、ユーザーの説明を足して 1-3 文で再構成する- brief 自体が無ければ、ユーザーの説明、素材フォルダ名、ファイル名、撮影時期の手掛かりから推定する
抽出ルール:
- 曖昧なラベルではなく、「誰が・何をしている・どんな文脈か」を入れる
- 編集意図だけでなく、映像に実際に映っている対象と文脈を書く
- 短すぎる単語 1-2 個で済ませない
- 確証のない固有名詞や出来事を捏造しない
Step 3: skip / provider オプションを決める
--skip-sttセリフ不要の B-roll only、一括素材が無音中心、または今回は映像理解だけで十分なときに使う。asset 単位で無音を自動判定するのとは別で、CLI 全体の STT を止めるフラグ。--stt-provider groq日本語素材を優先したいとき、または OpenAI で文字起こし品質が不安定だったときに first choice として使う。実装はwhisper-large-v3-turboを使い、--skip-diarizeしなければ pyannote で話者推定を追加する。--stt-provider openaigpt-4o-transcribe-diarizeの built-in diarization を使いたいときに選ぶ。pyannote 依存を増やしたくないときの選択肢。--skip-diarizesingle-speaker 素材、話者分離が不要、または pyannote が利用できないときに使う。Groq STT 経路でだけ意味があり、OpenAI STT では実質無効。--skip-vlm速度優先の技術 ingest だけ欲しいときに使う。これを付けるとsummary/tags/interest_points/display_name/peak_analysisの品質が大きく落ちるので、後続で clip triage するなら基本は使わない。--skip-peakquick pass でassets.json/segments.jsonだけ先に作りたいときに使う。peak_analysis.recommended_in_outが後続で必要なら使わない。--skip-vlm時は peak も走らないので、この flag はその場合ほぼ意味がない。--skip-media-link02_media/source_map.jsonと symlink 生成が不要な単発解析時のみ使う。--language言語が明確なときは与える。STT の初期推定を減らせる。
Step 4: 実行する
npx tsx scripts/analyze.ts <source-files...> \
--project projects/<project> \
--content-hint '子供の自転車練習の成長記録。公園での練習と上達の過程。' \
--stt-provider groq
Step 5: 実行後に品質チェックする
references/analysis-quality-check.md を参照する。
最低限やること:
03_analysis/assets.json、03_analysis/segments.json、03_analysis/gap_report.yamlを読む- STT 実行時は
03_analysis/transcripts/TR_<asset_id>.jsonを確認する - VLM を使ったつもりなら
segments.json.items[].summary/tagsとassets.json.items[].display_nameが埋まっているか見る - peak を使ったつもりなら
segments.json.items[].peak_analysis、peak_moments、recommended_in_outを確認する - downstream gate に進める前に
npx tsx scripts/validate-schemas.ts projects/<project>を走らせ、assets.jsonとsegments.jsonの schema / runner check を通す
Step 6: 結果を要約して次の skill へ渡す
- gap の有無と severity を要約する
- generic な
display_nameや弱い peak が多い場合はcontent-hint改善再実行を提案する - 後続が
select-clipsならpeak_analysisの有無を明示する
出力 artifact
03_analysis/assets.json03_analysis/segments.json03_analysis/gap_report.yaml03_analysis/transcripts/TR_<asset_id>.jsonただし STT 実行時のみ03_analysis/contact_sheets/*.png03_analysis/posters/*.jpg03_analysis/filmstrips/*.png03_analysis/waveforms/*.png02_media/source_map.jsonただし--skip-media-linkを使わない場合のみ
注意事項
peak_analysisは別ファイルではなくsegments.json.items[].peak_analysisに書き戻される- 実装上の visual semantic field 名は
visual_tagsではなくtags display_nameは VLM のsummary/tagsから生成される。a_person_is、a_child_is、clipのような generic name は hint 不足や VLM 解像度不足の兆候GEMINI_API_KEYがない場合、scripts/analyze.tsは warning を出して VLM を自動スキップする。このときgap_report.yamlが空でも VLM 成功とは限らないので artifact 本体を必ず見るgap_report.yamlは canonical artifact だが、blocking 判定は単純な件数ではない。runtime/mcp/gap-projection.tsでは ingest / segment の error を主に blocking として扱うscripts/validate-schemas.tsはassets.json/segments.jsonを検証するが、gap_report.yaml自体は検証対象ではない。gap は別途読むこと