| name | build-brand-clip-library |
| description | build a reusable, indexed clip library from a brand's own videos — download N brand-owned videos, watch each, cut semantically-named clips, and write a searchable clip index. use when a brand has its own footage (launch films, product demos, explainers, existing ads) that should be mined for reusable cuts before producing new ads. |
build-brand-clip-library
Purpose
Turn a list of a brand's own video URLs into an indexed, reusable clip library: download the videos, watch each one, cut semantically-named clips, and write a searchable clip index. The index lets a downstream editor or agent find the right footage for any ad beat — "need a UI demo of the dashboard", "need an end card", "need a finance b-roll shot" — without re-watching every video.
This is the footage counterpart to research-new-brand (which produces research + generated assets). Run it whenever a brand has real footage worth reusing.
Inputs
brand (required) — short slug used as the top-level project folder, e.g. perplexity, amex.
product (optional) — product/campaign focus, used in the index filename and headings.
video_urls (required) — list of brand-owned video URLs (YouTube etc.). Brand-owned only — see Decision Rules.
output_dir (optional, default <brand>/brand-assets/) — where source videos and the clips/ folder live.
max_height (optional, default 1080) — max download resolution.
Composed Atoms
download-youtube-video — fetch each brand video as a local mp4 (one call per URL).
trim-video-clips — cut a source video into named clip files from a {name, start, end} spec.
- External skill:
watch:watch — download/transcribe/extract frames so the clip windows can be chosen.
Workflow
- Validate. Confirm
video_urls are brand-owned (see Decision Rules). Verify yt-dlp and ffmpeg are installed.
- Scaffold. Create
<output_dir>/ and <output_dir>/clips/.
- Download. For each URL, run
download-youtube-video into <output_dir>/, naming each file a clean <video-slug>.mp4. Keep subtitles/.info.json when available — they speed up watching. Skip a URL cleanly on failure and log it.
- Watch + plan clips. For each downloaded video, run
watch:watch (frame grids + transcript) and build a shot-by-shot understanding. Identify 10–20 self-contained segments worth keeping as reusable footage — UI demos, product close-ups, b-roll, hero shots, key VO lines, end cards. For each segment record: a semantic name, in/out timecodes, a one-line visual description, an audio/VO note, a "best for" use, and tags.
- Cut. For each video, write a
clips.json spec ([{name, start, end}], names prefixed <video-slug>-<moment-slug>) and run trim-video-clips to cut clips into <output_dir>/clips/.
- Index. Write
<brand>/<brand>-<product>-clips-index.md following references/clip-index-template.md: a source-videos table, a per-clip entry for every cut clip (file, timecode, visual, audio/VO, best-for, tags), and a "Clip Finder" section that groups clips by need and tag.
- Manifest. Write
<output_dir>/clip-library-manifest.json listing source videos, every clip file, and which steps ran.
Decision Rules
- Brand-owned only. Only process videos the brand owns or has clear rights to (their channel, their ads, their press assets). Refuse third-party content; record the ownership basis in the manifest. The clip library is brand-owned footage — keep rights clean.
- Skip, don't stop. If a video fails to download or
watch:watch cannot decode it, skip that video, log it in the manifest, and continue with the rest.
- Semantic, stable names. Clip files are
<video-slug>-<moment-slug>.mp4 — descriptive and stable so the index stays valid across re-runs.
- Idempotent re-runs. Do not re-download a video that already exists;
trim-video-clips skips clips that already exist unless --overwrite is passed.
- Aspect ratio. Brand films are often 16:9 while social ads are 9:16 — note in the index that clips may need reframing/cropping for vertical placements.
Output
<output_dir>/ — downloaded source videos (<video-slug>.mp4).
<output_dir>/clips/ — semantically-named clip files + a per-cut manifest.json from trim-video-clips.
<brand>/<brand>-<product>-clips-index.md — the searchable clip index.
<output_dir>/clip-library-manifest.json — run manifest (source videos, clips, steps run, status, warnings, errors).
Quality Checks
- Every clip file in
clips/ has a matching entry in the clip index, and every index entry has a file on disk.
- Clip names are semantic and prefixed by their source video.
- Clip timecodes are valid (in < out, within the source duration).
- The "Clip Finder" section covers every tag used across clip entries.
- The manifest lists every source video and clip, and
status is one of pass, fail, needs human review.
Failure Modes
- A video is private / age-restricted (HTTP 403) —
download-youtube-video flags it; skip and log, ask the user for an alternate source.
- A downloaded video is corrupt / undecodable by
watch:watch — skip, log, continue.
yt-dlp or ffmpeg missing — install before running (brew install yt-dlp ffmpeg).
- A URL is not brand-owned — refuse it and report rather than building the library on unlicensed footage.
watch:watch unavailable — the molecule cannot choose clip windows; report blocked rather than guessing.