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 theclips/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_urlsare brand-owned (see Decision Rules). Verifyyt-dlpandffmpegare installed. - Scaffold. Create
<output_dir>/and<output_dir>/clips/. - Download. For each URL, run
download-youtube-videointo<output_dir>/, naming each file a clean<video-slug>.mp4. Keep subtitles/.info.jsonwhen 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.jsonspec ([{name, start, end}], names prefixed<video-slug>-<moment-slug>) and runtrim-video-clipsto cut clips into<output_dir>/clips/. - Index. Write
<brand>/<brand>-<product>-clips-index.mdfollowingreferences/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.jsonlisting 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:watchcannot 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-clipsskips clips that already exist unless--overwriteis 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-cutmanifest.jsonfromtrim-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
statusis one ofpass,fail,needs human review.
Failure Modes
- A video is private / age-restricted (HTTP 403) —
download-youtube-videoflags it; skip and log, ask the user for an alternate source. - A downloaded video is corrupt / undecodable by
watch:watch— skip, log, continue. yt-dlporffmpegmissing — 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:watchunavailable — the molecule cannot choose clip windows; report blocked rather than guessing.