broll-pick
Selects B-roll cutaways for one short. Claude reads the clip transcript +
chunks.json (from chunk-captions) + the source ingest.json, picks the 3-5
strongest visualizable nouns/topics (NOUN/VERB/EMOTION/PIVOT), and spawns
multiple short cutaway windows per topic — each intercut with the speaker, each
preferring distinct footage. Windows are expressed as whole chunk-index ranges
so no cut lands mid-word.
Per window: keyless YouTube discovery via the mcptube-bundled yt-dlp
(ytsearchN:<query> — mcptube discover is NOT used, it requires an LLM API
key the stack doesn't have), then mcptube add the candidate, sample 3 frames
via mcptube frame, and show Claude the frame grid (claude -p vision) to pick
the best on-subject shot or reject. On reject, the query is rewritten once
(literal↔metaphorical) and retried; a second miss drops the window — no fallback
footage. Chosen segments download via yt-dlp --download-sections into
work/<id>/broll/broll_NN.mp4.
Invoke
.claude/skills/broll-pick/broll-pick.sh <clip_transcript.json> <chunks.json> <ingest.json> <out_broll_plan.json>
clip_transcript: per-clip transcript withwords[](clip-local times)chunks: chunk-captions output (chunks[]witht0/t1/text)ingest:work/<id>/ingest.json(title + source url)out: path forbroll_plan.json; b-roll clips land in<ingest_dir>/broll/
Env
BROLL_VISION_CAP(default 10) — max Claude vision calls per clip.BROLL_PICK=0— disable; emits an empty plan.MCPTUBE_BIN,MCPTUBE_YTDLP— override binary paths.
Output (broll_plan.json)
{
"picks": [
{"t0": 4.31, "t1": 6.02, "topic": "hippopotamus", "anchor_word": "hippo",
"query": "hippo swimming underwater", "clip_path": "/abs/work/<id>/broll/broll_03.mp4",
"source": {"video_id": "abc123XYZ", "title": "...", "url": "https://youtu.be/abc123XYZ",
"t0_src": 12.4, "t1_src": 14.1},
"verified": true}
],
"ingested_video_ids": ["abc123XYZ"],
"vision_calls_used": 4,
"vision_cap": 10,
"chunks_mtime": 1746000000.0
}
No anchors / all queries miss → {"picks": [], "ingested_video_ids": []}, exit 0.
Idempotency
Caches on transcript+chunks+ingest mtimes via <out>.pickmeta.
Notes
- Records every
mcptube add-edvideo_idiningested_video_idsfor broll-cleanup. Never the podcast source (filtered by ingest url id). - CPU: 3 frames per candidate, reuses
_lib/encode.shthread caps downstream.