Agent skill

B-Roll Finder

by louisedesadeleer in louisedesadeleer/b-roll-finder

Finds and places b-roll on a talking-head video: classifies each moment, searches suitable sources and returns a short list of candidates for you to pick from.

MITAuto-check passedMedia & Creative

Install B-Roll Finder

skills CLI
$ npx skills add louisedesadeleer/b-roll-finder --skill find-broll -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install louisedesadeleer/b-roll-finder find-broll --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
find-broll
GitHub stars
123
Token cost
~7.1k tokens
SKILL.md length
3,969 words
Files
8 (incl. scripts)
Skills in repo
1
Repo updated
First seen
Licence
MIT

At a glance

Finds and places b-roll on a talking-head video: classifies each moment, searches suitable sources and returns a short list of candidates for you to pick from.

  • Works in 5 steps: Audio — does the user talk over b-roll… → Stills motion — static images get a very… → Source attribution — credit each… → …
  • Adding cutaway footage, memes or screenshots over a talking-head video
  • SKILL.md covers ⛔ USER OVERRIDES ARE LAW — and…, ⛔ STEP 0 — ONBOARDING GATE…, The one rule that governs… and The taste profile — load it…, plus 23 more sections
  • Runs Python scripts from its folder; calls ffmpeg and yt-dlp; reaches youtube.com and platform.twitter.com

What it does

The skill sources footage, memes and screenshots to lay over a talking-head edit, working from the transcript. For each moment it classifies what kind of cutaway is needed, limits the search to suitable sources, scores what it finds and returns a contact sheet of vetted candidates timed to the spoken word. The agent never makes the final selection; that stays with you.

A taste profile, TASTE.md, is loaded before any sourcing. Unless it begins with a Confirmed-by line carrying a name and date, the agent must ask four onboarding questions out loud and record the answers, and it may not infer them from memory or notes. A ban you state during a run, such as no memes, takes effect at once, is written into the profile's guardrails and is never revisited. Helper scripts ship with it: cdp_capture.py, render_cutaways.py and zoom_still.py.

When your agent uses it

  • Adding cutaway footage, memes or screenshots over a talking-head video
  • Sourcing b-roll for a podcast or tutorial intro from its transcript
  • Finding clips for each beat of an edit and placing them on the right word

Example prompts

  • “/find-broll for the intro of this podcast episode, transcript attached.”
  • “Source clips for this edit, but no memes and nothing political.”
  • “Find screenshots to lay over the part where I talk about the new dashboard.”

Requirements

  • A transcript of the video
  • A taste profile (TASTE.md) confirmed through the onboarding questions

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Audio — does the user talk over b-roll (strip ALL audio: ffmpeg -an) or want the clip's sound?
  2. Stills motion — static images get a very subtle Ken Burns zoom-in by default (~1.5%/sec, centered, capped ~2%/sec); offer opt-out to fully…
  3. Source attribution — credit each b-roll's source in small text bottom-right? Options: off · white · black · auto (contrast-pick per clip)…
  4. Concept motion graphics (Remotion) — generate on-brand motion graphics for concept/stat/chart beats? If yes, ask for the path to an…
  5. AI-generated b-roll — off by default; opt-in only for beats with no real footage, via a quality model the user names. Never silently…

What it can do on your machine

Read from SKILL.md and the folder at commit 36b8a56. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 3 files in scripts/ (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • ffmpeg
    • yt-dlp

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • youtube.com
    • platform.twitter.com
    • cdn.syndication.twimg.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

B-Roll Finder loads about 7.1k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 3,969 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~70
When it runs · the whole SKILL.md, loaded when a task matches
~7.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from louisedesadeleer/b-roll-finder at commit 36b8a56, republished under its MIT licence (© louisedesadeleer). 3,969 words, ~7,123 tokens.

Download SKILL.mdSave it as .claude/skills/find-broll/SKILL.md (or your agent's skills folder). This skill also uses 7 other files; get the full folder from GitHub.
name
find-broll
description
Source b-roll for a video edit — classify each moment, scope the search, return vetted candidates, place on the word. Use when the user says "find b-roll", "/find-broll", "source clips for this edit", or wants footage/memes/screenshots to lay over a talking-head video.

B-Roll Finder — skill methodology

A reusable methodology for sourcing and placing b-roll on talking-head video. Genericized from a working agent skill. Adapt paths and brand tokens to your own setup.

⛔ USER OVERRIDES ARE LAW — and they persist

When the user states a preference or ban mid-run ("no memes", "no text cards", "nothing political"), it applies IMMEDIATELY and for the rest of the session, AND gets written into the profile's Guardrails right then — not at the end. A banned category is never sourced again, never proposed again, never "just one candidate to check". Violating a stated ban is the worst failure this skill can make: it tells the user the agent doesn't listen.

⛔ STEP 0 — ONBOARDING GATE (run this check before ANYTHING else, every session)

Open the profile (TASTE.md or the user's fork). The ONLY thing that skips onboarding is a literal Confirmed-by: <name> (<date>) line at the top of the profile. No line → ask the four onboarding questions (below) out loud, write the answers into the profile, add the line. This is NOT optional and NOT inferable:

  • Do NOT infer the answers from CLAUDE.md, memory, prior conversations, or this profile's prose — even if you are confident you know them. Asking IS the feature.
  • The shipped TASTE.md is an EXAMPLE, even if the current user is its original author. Author ≠ confirmed.
  • A CLAUDE.md pointer that says "load my taste profile" does not count as confirmation either — check for the line.
  • "redo my profile" re-triggers onboarding at any time.

The one rule that governs everything

The agent NEVER picks the final b-roll. The user does. The right clip is often a taste call. This skill's job is to narrow the funnel — classify each moment, scope the search to trusted/authoritative sources, score candidates, and hand back a tight contact sheet. The user makes the final pick.

The taste profile — load it before sourcing anything

Curation is half the skill. Every run starts by loading a taste profile: the b-roll fingerprint (which types, how fast to cut), the trusted-source list tagged by topic, and the guardrails. This repo ships with a working default — TASTE.md, revealed from real published videos — so the skill has good taste out of the box. Use it as-is until the user builds their own (TASTE.md's "Make it yours" section covers the import-then-prune mechanism: pull their YouTube subscriptions via yt-dlp --cookies-from-browser, prune together, then reveal their fingerprint from their own published videos).

Onboarding preferences (ask once, store in the profile)

When onboarding fires: the shipped TASTE.md is an EXAMPLE profile (the author's), not the user's. On first run, check the profile for a Confirmed-by: line naming the current user. Absent → run onboarding: ask the questions below, write the answers into the user's profile (their fork of TASTE.md), and add Confirmed-by: <user> (<date>) at the top. Present → skip onboarding and just load it. The user can re-trigger anytime with "redo my profile".

Ask these on first run and write the answers into the taste profile (TASTE.md ships with one set of answers; confirm they fit):

  1. Audio — does the user talk over b-roll (strip ALL audio: ffmpeg -an) or want the clip's sound?
  2. Stills motion — static images get a very subtle Ken Burns zoom-in by default (~1.5%/sec, centered, capped ~2%/sec); offer opt-out to fully static. Method matters more than the setting — see "Stills motion" below.
  3. Source attribution — credit each b-roll's source in small text bottom-right? Options: off · white · black · auto (contrast-pick per clip). The credit is the source's canonical name + platform ("Vinexposium / YouTube", "Decanter") — short, never a URL. If the footage already carries its own badge bottom-right, move the credit bottom-left for that clip. Note: an on-screen credit is etiquette, not a license — official/authoritative sources remain the real copyright posture.
  4. Concept motion graphics (Remotion) — generate on-brand motion graphics for concept/stat/chart beats? If yes, ask for the path to an EXISTING Remotion project (+ brand tokens) and write it into the profile. Rendering a comp in an existing project is part of the lean path; scaffolding a new project is a one-time setup step that needs explicit permission (never mid-run). No project + no permission → concept beats use real authoritative footage or get flagged, never silently skipped.
  5. AI-generated b-roll — off by default; opt-in only for beats with no real footage, via a quality model the user names. Never silently substitute cheap AI stock.

🔓 Standing authorization — invoking the skill IS the permission

Do NOT ask conversational permission for access or searches while sourcing — running /find-broll already authorizes the skill to act on the user's behalf. Never ask "want me to search/look up/access X?" for:

  • Web searches, news/headline lookups, oEmbed/embed endpoints
  • yt-dlp metadata searches and downloads of public videos/channels
  • Headless-browser captures of public pages (incl. clicking through cookie/consent walls)
  • The user's logged-in browser or browser cookies for sourcing/reading (profiles, posts, walled pages)
  • Reading local files, transcripts, prior project folders, the user's asset library

Just do it and show the result. The user's taste checkpoints stay: the plan approval before sourcing and the final pick on taste-route beats. The ONLY things that still warrant a question: publishing/posting anything outward, paid actions, deleting user files, and installing heavy dependencies. Ask-permission friction everywhere else is a bug, not politeness.

⚡ LEAN PATH IS THE DEFAULT — the funnel is for taste calls, not everything

The skill earned trust through restraint; heavyweight process makes output WORSE, not better (tested 2026-06-11: a full-funnel run took ~10× longer and shipped worse composition than the lean run). Defaults:

  • Plan approval IS the pick. When the user approves the beat plan ("go for it"), source ONE best candidate per beat for objective routes (Entity/Receipts/Product) and place it. NO multi-candidate sourcing, NO contact sheets. (Contact sheets exist only when the user EXPLICITLY asks for options on a beat — and meme/cultural beats are never auto-sourced at all; see the routing table.)
  • Research depth is bounded at plan time. Verify referents enough to source accurately; do NOT exhaust every sourcing route before the plan. The escalation ladder fires only AFTER the user has agreed a beat and the easy routes failed — never speculatively.
  • Per-beat time box: if a single beat's sourcing exceeds ~5 minutes, place the best-available candidate or drop the beat and flag it. One stubborn artifact must not stall the edit.
  • One verify pass + targeted fixes beats endless polishing. Render → grid → fix the failures → re-verify only the fixed beats.
  • NO RETRIES — first failure switches, second failure drops. A method that fails once is NOT retried (not with tweaked flags, not "one more time") — switch to a different method immediately. If the second method also fails, DROP the beat, flag it in the plan, move on. A beat is never worth a third attempt; the edit ships without it. This applies to everything: captures, downloads, renders, browser actions. (Louise: "stop doing things that keep failing, just skip to save time.")
  • Never auto-install heavy dependencies mid-run (conda, aligners, etc.) — use the fallback, note it, offer the install after delivery.
Source by SOURCE, not by beat (the big sourcing speed-up)

After the plan is approved, cluster beats by where their asset lives, then fetch each source ONCE:

  • One full-page capture of the subject's website often covers 4–6 beats (history, team photo, map, packshots) — crop per beat from the same capture.
  • One official channel/film often covers several beats (an aerial, a close-up, a process shot) — download once, cut multiple windows.
  • Run all downloads as ONE batched background job (metadata-only search first, download only the chosen items); run captures as a second batch in parallel. Never fetch serially beat-by-beat.
  • Cache raw downloads next to the project (assets/raw/) so re-renders and v2s never re-fetch.

Accuracy over volume

Fewer, perfectly-accurate beats beat lots of mediocre ones. The habit to kill is keyword-matching to hit a quota.

  • Every beat passes a per-citation interpretation — write "what is this line actually about?" first, then source THAT. If you can't source something that accurately illustrates the real point, drop the beat — don't pad. No b-roll is better than wrong b-roll.
  • Default cadence = front-loaded: dense, punchy b-roll in the intro/hook, then sparse and precise through the body.
  • But "skip" is the LAST resort, not the default. Before proposing skip for a beat, walk the full palette out loud — receipt? headline? face? product UI? concept graphic? — and only skip when every lane genuinely fails. A rhetorical line with no proper noun is exactly when a sentiment receipt or a concept graphic shines.

Understand the TOPIC first, then source the MEANING — not the keywords

  1. Read the whole transcript and understand the thesis BEFORE sourcing anything. Context decides what illustrates each line.
  2. B-roll illustrates the POINT, not the words. The proper noun in a sentence is often NOT the referent:
    • "X from Company" → the person and their work, not the company logo.
    • "like Company did" → the thing Company did.
    • "what Person said" → the said-thing (their quote/post/essay), not their face.
  3. Literal vs evocative: concrete nouns (a product, a named person, an event) → show the actual thing. Actions & abstractions → show something that conveys it; don't reenact literally.
  4. Mandatory reference sweep — every beat: is there a REAL ARTIFACT behind this line? A quote, a stat, "people are saying", a named company event, "I saw/read" — almost always means a tweet, headline, review, or post exists. That artifact is a default candidate; sourcing it is the skill's job, not an extra the user must request.

Phrase-type → what to source (the judgment table)

When the narration is…Source this
"people are saying" / discoursetweets, headlines, posts, search-result screenshots
a number / stat ("$24/mo", "750 sign-ups")the figure ON SCREEN — pricing page, dashboard, chart, stat card
growth / "went viral"a graph going UP, or the viral post itself with its metrics
decline / "tanking"a graph going DOWN, error screens, the failing thing
"research shows" / authoritythe study/paper headline or the expert on camera
a direct quotethe authentic post/blog screenshot (beats a synthetic quote-card), or them saying it
an era / "back in the day"archival/vintage footage of that period
a placeestablishing shots of that place
comparison / "X vs Y"sequential full-bleed singles — never an agent-built split-screen
"how it works" / step-by-stepscreen recording or motion graphics of the steps
a story with actions ("every morning he'd…")the PLACES & ACTIONS, evocatively — never a literal reenactment
a metaphor ("like a rocket")the metaphor object ONLY if it lands — metaphors default to SKIP
an emotion / reaction beatpropose the moment + register; the user supplies the meme
the creator's own content ("my video")self-source their actual clip/post — not a search

Genre → coverage defaults (what type, how much)

Genre predicts b-roll TYPE and density better than topic does (style + cadence answers from intake override these):

  • Competitor / drama → receipts dominant, heavy (~40–60% coverage)
  • Opinion / explainer → text/concept cards + receipt bursts (~20–30%)
  • Storytelling / listicle → people, archival, products (~40–60%)
  • Podcast / webinar / interview → light punctuation (~5–10%); b-roll marks references & claims, the talking head carries the rest

Routing — three+ kinds of b-roll go to three+ sources

Classify EVERY moment before searching:

RouteTriggerSource
ReceiptsTime-sensitive — drama, news, complaints, a current claim/statTweets / article headlines / reviews, recency-sorted, captured as clean screenshots
EntityA person, a physical product, or a historical momentThe official / authoritative channel — the canonical clip, not a random upload
ConceptAn abstract idea you'd have to draw (a process, a mental model, a stat)Custom motion-graphics (e.g. Remotion) in your brand style — the DEFAULT when the profile has a Remotion project path — or real footage from the authoritative source

⛔ Cards never replace real footage of a literal thing. If the beat names a concrete entity (grape varieties, a product, a place) and real footage exists, a generated text card is a FAIL — even if the user's fingerprint shows they like cards. Cards are for ideas with NO literal footage. (2026-06-11: a "three grapes" beat got a navy text card while the official film had the actual clusters — wrong.) | Cultural / Meme | A creator clip or joke where taste decides | NEVER searched or fetched by the agent. Propose the MOMENT + register ("punchline at 2:31, deadpan") in the plan; the user supplies the meme from their library — or strikes the beat. Agent-found memes have failed every time they've been tried. |

Litmus (in order): Happening now? → Receipts. A person / product / event? → Entity (official source). An abstract idea? → Concept (motion-graphics). A reaction beat? → Meme (user's library).

YouTube's sweet spot is the Entity route (people, products, historical moments). Don't force it onto abstract ideas — those are Concept jobs.

Person clips — source the MOMENT, not the NAME

A clip merely containing the person is NOT relevant b-roll (the #1 person-clip failure):

  1. Write the mention-context first: what is the line saying ABOUT the person — the trait, the action, the claim, the event?
  2. Query = person + mention-context, never the bare name. "Steve Jobs iPhone keynote 2007", not "Steve Jobs". Bare-name searches return generic press-junket clips.
  3. Verify before presenting: for each candidate, fill in "in this clip, X is <doing/saying what, where, when>" from the title/date/auto-subs. Can't fill it in → not a candidate.
  4. No context match found → say so; offer the canonical clip explicitly flagged "generic", or switch palette to their work/quote/headline (often better anyway).
  5. "The show/podcast" ≠ "this episode" — a reference to a show sources the show's persistent branding, not one episode's guest art.

The palette — MIX it, never default to website screenshots

  • Faces (video) — for a named person, a live clip of them talking (never a frozen headshot). Partial-frame / split-screen subjects → blurred-fill, never hard cover-crop. For a podcast/panel edit, the guests are ON CAMERA in the source recording — crop their tile as live video instead of hunting externally. A headshot of someone the audience won't recognize is DEAD b-roll — for niche people, show their WORK (their post, product, talk) instead of their face; famous faces should appear in context/action, not as static portraits. ⛔ And NEVER cut to a speaker's own tile as b-roll inside the same video they're speaking in — the audience is already looking at them; it reads as a glitch. Tile-cropping is for using their face in OTHER videos.
  • Product / UI — the actual app UI or a real screen-recording (prefer own-recording > official channel > nothing; reject random third-party tutorials). Demos must be the MOST RECENT available — product UIs change fast; check upload dates, present them next to candidates.
  • Receipts — tweets, headlines, reviews, search results. For a named company, prefer a news headline about a real event (IPO, funding, milestone) over the homepage.
  • Reference screenshots — the real post/essay/page cited (an authentic screenshot beats a synthetic quote-card). The subject's own website, captured full-page and cropped per viewport, is a goldmine — history pages, team photos, maps, product pages.
  • Concept motion-graphics — for ideas, charts, stats. Build on-brand; never synthetic-looking stock.
  • Real / evocative footage — stock that conveys a story/action/mood. Eyeball every frame for watermarks, burned-in captions, and AI-slop.
  • Memes / reactions — from the user's curated library only; the agent proposes the moment, never the meme. If the profile or the user says no memes: the category does not exist.

If a plan is >60% website screenshots, it's wrong.

Show full SKILL.md (1,503 more words)Show less

Cadence guardrails — restraint reads as taste

  • Beats run ~2–4s. Anything under ~1.2s is unreadable (no sub-second shots except inside ONE deliberate burst montage).
  • Max ONE burst montage per intro (3–4 quick stills on a list-beat). Two+ bursts = chaos.
  • Max ONE long hold (>5s) per intro, and only on a genuine explainer beat. An 8-second static map is dead air.
  • When in doubt: fewer, real, obvious. The strongest edits use one clearly-right asset per beat, not the most assets.

Motion-first — video beats a static page

When BOTH a moving and a static version of a source exist, take the moving one: the product's own demo video over its homepage; a real screen-recording of scrolling over a static capture; a live excerpt over a headshot. Stills stay right where READING is the point (a tweet, a headline, a review). Rubric tie-breaker: equal relevance → motion wins.

Stills motion — sub-pixel subtle zoom only; ffmpeg zoompan is banned

Hard-won distinction — the ban is on the METHOD, not the effect:

  • ffmpeg zoompan / crop-pans / scroll-pans are BANNED, at any speed, with any supersampling. They sample on integer pixel steps, so even a ~1%/sec zoom stutters. Tested exhaustively (4× lanczos supersample → zoompan → downscale): still shaky. Don't burn time re-attempting.
  • Sub-pixel rendering is the legitimate path and produces a smooth subtle zoom:
    • PIL recipe (proven): per-frame img.resize((W,H), Image.LANCZOS, box=<float coords>) — float box coordinates = sub-pixel sampling — piped as rawvideo into x264. ~30 lines of Python.
    • Remotion (CSS transform scale) is equally valid when a project is scaffolded.
  • Defaults: zoom-IN only, centered, ~1.5%/sec, cap ~2%/sec, stills only — no pans, no zoom-outs, never synthetic motion on top of real video. Per-profile opt-out → fully static.

Eval rubric — score every candidate before showing it

Score 1–5 and drop anything below the bar:

  1. Recency fit — is the beat time-sensitive or evergreen? Time-sensitive + old clip = FAIL.
  2. Source authority — primary/official/reputable vs random creator.
  3. Relevance — depicts the exact named thing, not a loose association. Person clips: relevance = context-match.
  4. Recognizability / impact — reads instantly, screenshots clean.
  5. Format fit — silent-able, ~2–6s, full-bleed-able, ≥720p.

Check time-sensitivity first — a dated tweet from this month beats a years-old YouTube clip for a current story.

Search syntax — scoped beats open, always

  • Channel-scoped YouTube search is the DEFAULT for Entity beats: yt-dlp "https://www.youtube.com/@<handle>/search?query=<q>" --flat-playlist --print "%(title).75s ||| %(duration_string)s ||| %(id)s" — search INSIDE the official/trusted channel. ytsearchN:<query> is the fallback; fully open results get flagged "⚠️ outside trusted sources".
  • Metadata first, download later: --flat-playlist --print costs seconds; download only the chosen winners (-f "bv*[height<=1080]+ba/b").
  • Tweets without login: https://platform.twitter.com/embed/Tweet.html?id=<TWEET_ID> renders a clean card headlessly, no auth (&hideThread=true; capture with scripts/cdp_capture.py). The tweet's real attached media resolves via https://cdn.syndication.twimg.com/tweet-result?id=<ID>&token=a. Verify what the attachment actually shows before shipping it.
  • Generic evocative stock is YouTube's weak spot: add "free to use / no copyright" qualifiers; REJECT watermarked stock-site previews and clips with burned-in captions; if YouTube only yields junk, recommend a real stock site (Pexels / Mixkit / Coverr) instead.

Once a beat is agreed, sourcing it is the AGENT's job — the escalation ladder

"Login-walled" is a claim you prove by attempting, not a label for punting. Exhaust ALL of these before handing a beat back to the user:

  1. Local artifacts — grep the user's notes/downloads/prior sessions for the exact link or handle.
  2. Identity hunt — web-search via mention-context (distinctive phrases beat bare names); resolve shortlinks; oEmbed endpoints identify authors without auth.
  3. Plain yt-dlp — public profiles/videos usually need NO login.
  4. yt-dlp --cookies-from-browser — the user's logged-in cookies beat most walls.
  5. Headless Chrome + CDP — for captures behind consent walls: click "accept" in EVERY frame context (CMPs render in iframes), with overlay-removal as fallback; then VERIFY the capture by looking at it. Never deliver a screenshot you haven't visually inspected.
  6. The user's logged-in browser (browser-automation MCP) when available.
  7. Only if ALL genuinely fail → a precise you-source list, with a note of what was tried.

Placement timing — land ON or just AFTER the word, never before

  • Anchor to when the keyword is spoken, then add a small lead (~+0.2s) so the cut lands as/just after it. B-roll before the word reads as a mistake.
  • Timing source: Whisper word-level timestamps (--word-timestamps True, one pass during transcription — no extra tooling). Find the keyword's word time and anchor +0.2–0.5s after it. Whisper word-ends run slightly early and embed pauses inside word durations, so bias LATER when unsure — late reads as intentional, early reads as a mistake.
  • (MFA forced alignment was tried for ~10–20ms precision and REMOVED 2026-06-11 — the runtime cost wasn't worth it; whisper + later-bias is accurate enough in practice. Don't reintroduce it.)
  • For punchlines, land on the beat after the punchline.
  • Connect adjacent b-rolls: if two cutaways sit closer than ~a half-sentence apart, extend the first to the second's start — a <2s flash of the speaker's face between them reads as an error. (Extend the earlier clip; never start the next one before its keyword.)

Composition — full-bleed, no composites

  • Cover-crop, never letterbox: scale=W:H:force_original_aspect_ratio=increase,crop=W:H.
  • No agent-built composites: no split-screens, no 2-ups, no clever framing. Two referenced people → sequential full-bleed singles. The ONE allowed treatment beyond cover-crop is blurred-fill (enlarged blurred copy behind a fitted clip).
  • Partial-source / split-screen subjects: blurred-fill, never cover-crop (cover-cropping a half-frame zooms hard into a face).
  • Don't upscale a tiny source to full-bleed — find a higher-res source.

Iteration discipline — the b-roll manifest

Across re-renders the #1 failure is silently DROPPING beats the user already approved. Keep a BROLL-MANIFEST.md next to the deliverable: one row per beat (in/out · beat · asset · status incl. which version approved it) plus a "Removed (do not re-add)" list. Before EVERY re-render: read the manifest, verify every approved beat is in the new cut, add the new ones, update statuses. Approved b-roll never disappears without the user explicitly cutting it.

Self-verification — look at every cut before the user does

After every render, extract a frame at every beat's midpoint AND every joint (b-roll↔b-roll, b-roll↔face), tile them into a grid, and LOOK at it. Fix and re-verify. A render isn't done until the grid is clean.

Explicit AUTO-REJECT checklist — a frame containing ANY of these fails, no judgment call:

  1. Burned-in captions/subtitles from the source clip
  2. Name-tags / lower-thirds identifying strangers
  3. Watermarks or channel logo bugs (corner badges from official bodies are a flagged exception, not a free pass)
  4. The speaker's own face/tile appearing as b-roll in their own video
  5. A generated card where the beat names a literal, filmable thing
  6. Template-looking composites (two portraits side by side, collage cards)
  7. Letterboxing, tiny floating content, or visible blur-edge framing errors
  8. A split-second sliver of talking head (<1s) between two cutaways — connect them: extend the first beat to the second's start (never start the second early)

Grade the grid against this list line by line — "looks fine" without the list is how watermarked clips ship.

Fetching & formatting (editor-friendly, silent, full-bleed)

  • Proxy FIRST for big sources: if the base video is 4K/HEVC/>500MB, transcode a 1080p working copy before anything (ffmpeg -hwaccel videotoolbox -i src -vf scale=1920:-2 -c:v h264_videotoolbox -b:v 6M -c:a aac proxy.mp4) — every later step (frame scans, renders) runs 5–10× faster against it.

  • Don't grab low-res pre-merged streams — select a real stream (-f "bv*[height<=1080]+ba/b").

  • Don't let --download-sections be the final cut (variable framerate stutters) — download the short clip, then trim with a re-encode.

  • Standard format: constant fps, cover-crop full-bleed, audio stripped:

    ffmpeg -ss <in> -t <dur> -i full.mp4 \
      -vf "fps=30,scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080,setsar=1" \
      -an -c:v libx264 -crf 18 -preset slow -pix_fmt yuv420p -movflags +faststart out.mp4
  • Attribution on → composite the small credit label (PIL-rendered PNG, ~70% opacity) via overlay during formatting (some ffmpeg builds lack drawtext).

Workflow summary

  1. Load the taste profile / set topic — TASTE.md (or the user's fork): fingerprint, preferences, and trusted sources filtered to this video's topic tag.
  2. Ask style + cadence — format (podcast / tutorial / fast-cut / heavy-intro) and density. These override genre defaults.
  3. Get the transcript — paste, pull from the editor, or transcribe (GPU Whisper, word-level). Long-form (>~10 min): score segments for b-roll value and select the high-value ones first — don't uniformly b-roll an hour.
  4. Classify + propose (no fetching yet) — annotate each beat with its interpretation, route, the reference sweep result, and the palette mix. Present the plan and wait for the user to react before sourcing.
  5. Constrained search — scoped to trusted/official sources; score candidates; verify person clips against mention-context; drop the weak ones.
  6. Contact sheet → user picks.
  7. (Optional) place & render — cut full-bleed + silent, anchored on the word, adjacent beats connected, manifest updated, self-verification grid before delivery.

Tools

  • Transcription: GPU Whisper for transcript text (large model — the transcript drives understanding, so text accuracy matters).
  • Anchor timing: Whisper word-level timestamps + later-bias (+0.2–0.5s past the keyword).
  • Search / download: yt-dlp (no API key); headless browser + CDP for public-page screenshots (consent walls: click accept in every frame context, verify visually).
  • Motion-graphics: Remotion (or similar), rendered full-bleed + silent.
  • Stills zoom: scripts/zoom_still.py (sub-pixel PIL float-box → x264; --blurfill for portrait/odd aspect; never zoompan).
  • Consent-wall captures: scripts/cdp_capture.py (headless Chrome via CDP — clicks "accept" in every frame context, CMP-iframe aware; CDP_SCALE=2 for crisp receipts).
  • Cutaway rendering: scripts/render_cutaways.py (segment-concat template: base visual replaced per beat window, audio untouched).
  • Compositing: ffmpeg; ImageMagick for contact sheets.

© louisedesadeleer, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 7 other files (scripts) in the repository root of louisedesadeleer/b-roll-finder.

  • SKILL.md
  • LICENSE
  • README.md
  • TASTE.md
  • banner.png
  • scripts/cdp_capture.py
  • scripts/render_cutaways.py
  • scripts/zoom_still.py

Open the folder on GitHubat commit 36b8a56

Compare with similar skills

B-Roll Finder next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

B-Roll Finder compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
B-Roll Finder this skilllouisedesadeleer/b-roll-finder123—~7.1kAutomated safety check: PassMIT
Remotion Best Practiceslyonjs/shortvid.io14732 repos~1kAutomated safety check: PassMIT
FFmpeg for Video Productiondigitalsamba/claude-code-video-toolkit2.2k3 repos~3.3kAutomated safety check: PassMIT
HyperFrames Video Entry Pointheygen-com/hyperframes58k3 repos~5.2kAutomated safety check: PassApache-2.0
Video Podcast Makerdtsola/xiaoyaosearch1k—~3.4kAutomated safety check: PassMIT
ShortsAgriciDaniel/claude-shorts218—~3.2kAutomated safety check: NotesMIT

Similar skills

  • Remotion Best Practices

    lyonjs/shortvid.io

    Best practices for Remotion - Video creation in React. An agent skill from lyonjs/shortvid.io.

    147 GitHub starsUsed in 32 repos~1k tokens
    Media & CreativeAuto-check passed
  • FFmpeg for Video Production

    digitalsamba/claude-code-video-toolkit

    Command recipes for converting, resizing, compressing, trimming and extracting audio from video with FFmpeg, including settings for Remotion projects.

    2.2k GitHub starsUsed in 3 repos~3.3k tokens
    Media & CreativeAuto-check passed
  • HyperFrames Video Entry Point

    heygen-com/hyperframes

    Entry point for making, editing and rendering videos from HTML compositions with HyperFrames, routing each request to the right workflow.

    58k GitHub starsUsed in 3 repos~5.2k tokens
    Media & CreativeAuto-check passed
  • Video Podcast Maker

    dtsola/xiaoyaosearch

    Turns a topic into a 4K horizontal video podcast through research, scripting, text-to-speech, Remotion rendering and background music, and can learn styles from references.

    1k GitHub stars~3.4k tokensUpdated 5 days ago
    Media & CreativeAuto-check passed
  • Shorts

    AgriciDaniel/claude-shorts

    Interactive longform-to-shortform video creator. An agent skill from AgriciDaniel/claude-shorts.

    218 GitHub stars~3.2k tokensUpdated 2 mo ago
    Media & CreativeAuto-check: notes
  • Black White Text Opener

    Pluviobyte/video-production-skills

    Create reusable black-background white-text opening animations for new videos.

    664 GitHub stars~1k tokensUpdated 2 mo ago
    Media & CreativeAuto-check passed

Works with

Questions about B-Roll Finder

What does B-Roll Finder do?

Finds and places b-roll on a talking-head video: classifies each moment, searches suitable sources and returns a short list of candidates for you to pick from. The skill sources footage, memes and screenshots to lay over a talking-head edit, working from the transcript. For each moment it classifies what kind of cutaway is needed, limits the search to suitable sources, scores what it finds and returns a contact sheet of vetted candidates timed to the spoken word.

When should I use B-Roll Finder?

B-Roll Finder fits situations like: adding cutaway footage, memes or screenshots over a talking-head video; sourcing b-roll for a podcast or tutorial intro from its transcript; finding clips for each beat of an edit and placing them on the right word.

How do I install B-Roll Finder in Claude Code?

Run `npx skills add louisedesadeleer/b-roll-finder --skill find-broll -a claude-code`. Or copy the skill folder (the louisedesadeleer/b-roll-finder repository) into .claude/skills/find-broll in your project. Claude Code loads it when a task matches its description.

How do I install B-Roll Finder in Codex?

Run `npx skills add louisedesadeleer/b-roll-finder --skill find-broll -a codex`. Or copy the skill folder (the louisedesadeleer/b-roll-finder repository) into .agents/skills/find-broll in your project. Codex loads it when a task matches its description.

Can I use B-Roll Finder in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add louisedesadeleer/b-roll-finder --skill find-broll -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/find-broll, .gemini/skills/find-broll, .github/skills/find-broll and .opencode/skills/find-broll in your project.

What does B-Roll Finder need to run?

Going by SKILL.md and its folder, B-Roll Finder needs Python for the scripts in its folder and the command-line tools its instructions call (ffmpeg and yt-dlp). Our summary lists: A transcript of the video; A taste profile (TASTE.md) confirmed through the onboarding questions.

Does B-Roll Finder access the network?

SKILL.md names 3 domains. In commands or code: youtube.com, platform.twitter.com and cdn.syndication.twimg.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.

Is B-Roll Finder safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does B-Roll Finder use?

B-Roll Finder is published under the MIT licence (from the LICENSE file in the skill folder). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does B-Roll Finder use?

About 7.1k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to B-Roll Finder?

Skills that share tags, products or a category with B-Roll Finder: Remotion Best Practices (lyonjs/shortvid.io, 147 stars), FFmpeg for Video Production (digitalsamba/claude-code-video-toolkit, 2.2k stars), HyperFrames Video Entry Point (heygen-com/hyperframes, 58k stars) and Video Podcast Maker (dtsola/xiaoyaosearch, 1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains B-Roll Finder?

louisedesadeleer (a GitHub user) maintains it in louisedesadeleer/b-roll-finder, which has 123 GitHub stars. The repository was last updated on June 11, 2026.

Source: louisedesadeleer/b-roll-finder on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.