⏳ This skill is pending AI review.
Scores will appear once the review pipeline completes.
ai-video-ads
An autonomous AI film producer. Given only a product (name, link or photo), Claude researches it, writes a catchy ~60 s ad script, designs the cast, product and locations, generates every image and clip itself in Google Flow and Grok Imagine (driven in the user's Chrome) or Higgsfield/Kling MCP, QC's each clip for drift, makes the voiceover, and cuts the final film with ffmpeg plus a CapCut kit — photoreal and consistent like the reference reels (Oraimo story ad, NorthQuest UGC ad, Pocari Sweat mini-film). Use whenever the user hands over a product or asks for an AI ad, AI commercial, product video, concept ad, brand film, AI short film, or "a video like this" — even if they name no tool.
Choose how to use this skill
You do not need every option. Choose the path your AI client supports. The stable page stays the same; versioned files are immutable.
1. Native installer
This listing has no registered native installer command. Use the complete package or source fallback below, depending on what your client supports.
Do not guess an installer command or replace an existing version without reviewing the diff.
2. Complete package recommended
Download the ZIP when available. It includes SKILL.md plus the references, security notes and version metadata.
No complete ProSkills package is published for this listing yet.3. Prompt-only
Copy the prompt above when the agent can read the stable page or when you want to adopt the workflow without installing a skill.
Need only the instruction file?
Download SKILL.md only if your client requires a single file. The complete ZIP is safer for a full installation because it preserves the references and release context.
No path installs or executes anything by itself. Your agent still needs access to the project files. Before updating, compare the installed version and review the diff.
// RATINGS
Not yet listed on ClawHub or SkillsMP
// README
AI Film Producer — a Claude Code skill
Hand Claude a product photo or link and it produces a ~60-second photoreal AI ad on its own: research → selling angle → script → cast, product and location sheets → keyframes → video clips in Google Flow and Grok Imagine (driven in your Chrome) → QC → voiceover, music, SFX, end card → final edit with ffmpeg, plus a CapCut kit with every element on its own track.
Built and tested on a real 57 s product film made with free-tier Flow credits and Grok.
Install
git clone https://github.com/Nova0x2/ai-film-producer-skill.git
cp -R ai-film-producer-skill/ai-video-ads ~/.claude/skills/
Windows: copy ai-video-ads to C:\Users\<you>\.claude\skills\.
Restart Claude Code and say: "Make an ad for this product" (attach photos), or run /ai-video-ads.
Requirements
| Need | Notes |
|---|---|
| Claude Code + Claude in Chrome extension | Claude drives Flow and Grok in your browser |
| Google Flow and Grok Imagine accounts | Sign in yourself in Chrome; free tiers work |
| ffmpeg + Python 3 | scripts/assemble.py does the edit |
| Voiceover (optional) | Any TTS; the skill was tested with local Kokoro |
| Music (optional) | Any licensed library you subscribe to (e.g. Epidemic Sound) |
| End cards / text (optional) | HyperFrames skills, or any PNG maker |
What's inside
ai-video-ads/
SKILL.md the 9-phase production pipeline Claude follows
references/browser-tools.md Flow and Grok UI map, credit costs, upload/download tricks
references/reference-reels.md the quality bar: three AI ads studied shot by shot
scripts/assemble.py EDL-driven ffmpeg editor (cuts, fades, audio ducking, overlays, -14 LUFS, CapCut kit)
The editor works on its own too:
python3 ai-video-ads/scripts/assemble.py edl.json --kit
The EDL format is documented at the top of the script.
Customise
- Change the default project folder (
~/Movies/AI Ads/) and default setting (Lagos, Nigeria) inSKILL.md. - Web UIs change: when Flow or Grok move a button, update
references/browser-tools.md.
Guardrails
Original characters only, a real brand's own claims only, unlicensed brand work labelled #conceptad,
and Claude never enters passwords or spends credits beyond the budget you approve.
License
MIT. Fork it, edit it, ship your own version.
// HOW IT'S BUILT
// FILES
5 files shipped with this skill. Inline text is the catalog copy. The upstream link is the source repository.
ai-video-ads/SKILL.md9.0 KB2e1273564ff5upstream ↗
--- name: ai-video-ads description: An autonomous AI film producer. Given only a product (name, link or photo), Claude researches it, writes a catchy ~60 s ad script, designs the cast, product and locations, generates every image and clip itself in Google Flow and Grok Imagine (driven in the user's Chrome) or Higgsfield/Kling MCP, QC's each clip for drift, makes the voiceover, and cuts the final film with ffmpeg plus a CapCut kit — photoreal and consistent like the reference reels (Oraimo story ad, NorthQuest UGC ad, Pocari Sweat mini-film). Use whenever the user hands over a product or asks for an AI ad, AI commercial, product video, concept ad, brand film, AI short film, or "a video like this" — even if they name no tool. --- # AI Video Ads — autonomous producer The user gives a product. Claude does everything else: research → concept → script → production bible → every image → every clip → QC → voice, music, graphics → ffmpeg edit → delivery. Quality bar: `references/reference-reels.md` . Rule zero: **nothing is animated until it exists as an approved still.** Consistency is decided at the image stage; the video model only adds motion. Only stop to ask the user when: a step costs more credits than the approved budget, a site needs him to sign in, a download needs his OK (ask once per project, listing what will be saved), or the music choice needs licensing. Everything else is Claude's call — decide, log it, move on. Project folder: `~/Movies/AI Ads/<product>-ad/` ``` research/ brief.md (facts, audience, competitors, ad references, product photos) script.md shotlist.md bible.md jobs.md (every prompt + tool + result, per shot) assets/ character/ product/ locations/ keyframes/ clips/ audio/ gfx/ edl.json final/ final/capcut-kit/ ``` ## Phase 1 — Research (≈15 min, free) 1. WebSearch + WebFetch: official site, specs, price, colours, packaging, tagline, the brand's own claims (an allowlist — never invent stronger ones), target customer, where it's sold. 2. Find 3–5 existing ads or creator videos for the product or its category (YouTube, IG, TikTok); watch the best 2 with `/watch` and note hook, pacing, shots, what's missing. 3. Collect real product images (official site, store listings) into `research/product/` — used only as references so the label and shape come out right. Need ≥1 clean front shot, ideally side/back/logo close-up. 4. Write `research/brief.md`: one-line product truth, audience, the single benefit to sell, the feeling, local setting (default Lagos/Nigeria unless the brand says otherwise), CTA. ## Phase 2 — Concept and 60 s script Write 3 one-line concepts, pick the strongest yourself (most visual, most surprising, one clear benefit), note why in `script.md`. Every concept must have a tiny story or running gag — not a feature list. 60 s structure (~20–26 shots of 1.5–4 s): | Time | Beat | Job | | --- | --- | --- | | 0–3 s | Hook | Odd image, bold line or question. Decides the whole ad. | | 3–12 s | Problem / world | Character, situation, the itch the product scratches | | 12–35 s | Product in action | Product enters; 2+ macro inserts; benefit shown, not said | | 35–50 s | Payoff / twist | Emotional win, the gag pays off, proof moment | | 50–60 s | Brand + CTA | Product hero shot, end card with name, tagline, CTA | Voice: either a voiceover (~130–150 words for 60 s, short punchy lines) or 3–6 short dialogue lines spoken on camera, plus music. Write the script as a two-column table: VISUAL | AUDIO, with timings that add up to 60 s. ## Phase 3 — Production bible (`bible.md`) - **Style anchor** (one line pasted into every prompt), e.g. "photoreal commercial, 35mm, soft natural window light, shallow depth of field, warm tones, unretouched skin texture". - **Cast**: identity block per character (age, skin, face shape, hair with exact style, build) + wardrobe per scene. Original people only. - **Product**: exact description (shape, colours, materials, label text as printed). - **Locations**: one line each + lighting state. - **Shot list** (`shotlist.md`): #, seconds, size, angle/POV, camera move, cast, product state, location, action, audio, tool. Neighbouring shots never share POV and distance band; one action + at most one camera move per shot; ≥2 product macros; one unusual POV. - **Credit budget**: shots × takes × cost, per tool, per day. Get the user's OK once. ## Phase 4 — Lock the assets (images) Method: Higgsfield `character-sheet` workflow rules (slot order, "photoreal-unretouched" realism module, mature adult structure, split-screen full body + close-up, negative tail). 1. **Character**: 4 portraits → choose the best → split-screen sheet + turnaround from it. 2. **Product**: upload the real photo; make a product sheet (front/side/back/logo macro) by *editing* that photo with Nano Banana Pro. Logo must match letter for letter. 3. **Locations**: empty plates, no people. 4. **Keyframes**: for every shot, compose its first frame (character + product + location references) as a still; for reveals also the last frame. Inspect each; fix with image edits. Save everything locally in `assets/` and `keyframes/` and log prompts in `jobs.md`. ## Phase 5 — Generate the clips Pick per shot (see `references/browser-tools.md` for the exact screens and clicks): | Shot type | Tool | | --- | --- | | Hero product shots, reveals, first→last frame moves | Flow, Veo 3.1 Quality / Fast, Frames | | Recurring character in new compositions, dialogue + lip-sync | Flow, Omni 1.1 Flash with Characters + voice (Ingredients) | | Cheap drafts, 10–15 s single takes, simple motion | Grok Imagine, image-to-video, 720p | | Many fast consistent cuts from one board (if Higgsfield has credits) | Higgsfield Seedance 2.5 `omni_reference` (method below) | Video prompt order: shot size + camera move → subject + ONE action → dialogue in quotes → setting → lighting → style anchor → Audio: line (ambience, SFX, "no music") → locks ("same face, hair, outfit and product as the reference; no on-screen text"). Draft cheap (Omni 360p, Veo Lite, Grok 480p), finish winners at 720p/Quality. Board method (Higgsfield, from its `ugc-video` workflow — load `references/ugc-board.md` and `references/ugc-clip.md` with `get_workflow_bundle_file`): one 21:9 `gpt_image_2` board of eight 9:16 panels → `seedream_v5_pro` realism cleanup → inspect → `seedance_2_5` `omni_reference` with [board, character, product] and a "Cut 1 (0–1.9s) … Hard cut to." × 8 prompt. Gives 8 consistent cuts per generation. Download each accepted clip to `clips/sNN_takeK.mp4`. ## Phase 6 — QC (every clip, no exceptions) `ffmpeg -i clip -vf fps=2,scale=360:-1 qc/sNN_%02d.jpg`, tile, Read. Reject → regenerate only that shot if any fail: face/hair/skin matches the master · outfit matches the scene · product shape, colour and logo exact · hands correct · no stray text/watermarks/other brands · speech clear and in sync · duration and 9:16 correct. Log verdicts in `jobs.md`. ## Phase 7 — Sound and graphics - **Voiceover**: Flow custom voice (on-camera dialogue) or local Kokoro TTS (`~/.venvs/kokoro`, see memory `tts-voice-setup`) for narration → `audio/vo.wav`. - **Music**: Epidemic Sound in the user's Chrome (logged in) — search genre + mood, choose by BPM, download full-mix MP3; land the beat drop on the first product cut. Fallback: Flow Music. Pick tempo to the cut (~100–120 BPM for lifestyle). - **SFX**: whooshes on transitions, product sounds (cap pop, click) from the clips or a library. - **End card + any text**: render in HyperFrames (`/hyperframes`) as a transparent MOV or PNG → `gfx/`. The local ffmpeg has no drawtext/libass, so never burn text with ffmpeg. - **Captions** only for spoken lines, house style. ## Phase 8 — Edit with ffmpeg Write `edl.json` (format in the script's docstring) and run: ``` python3 ~/.claude/skills/ai-video-ads/scripts/assemble.py edl.json --kit ``` It conforms every clip to 1080×1920 30 fps (crop-to-fill), trims in/out, speed-ramps, hard cuts or fades, mixes clip audio + VO + SFX + music with the music ducked under the voice, overlays graphics by time, normalises to -14 LUFS, and writes `final/` + `capcut-kit/`. Edit rules: cut on action; trim 0.2–0.4 s of dead head/tail from AI clips; hard cuts by default, fades only into the end card; land cuts on music beats; first frame must already be the hook. No colour grade beyond what the shots have. Watch the export (frames at every cut + loudness check) before calling it done. ## Phase 9 — Deliver `final/<product>_ad_9x16.mp4`, the CapCut kit, `script.md`, and a 5-line production note (concept, tools used, credits spent, known weak shots). Post caption with "#conceptad" when the brand didn't commission it. ## Guardrails - Original characters only; no real person's likeness without their consent and photos. - Real brands = spec/concept ads: exact logo, only the brand's own claims, labelled as concept. - No fake testimonials presented as real customers. - Downloads and spending: confirm with the user as above; never enter passwords.ai-video-ads/scripts/assemble.py9.2 KBfba53c65ed9dupstream ↗
#!/usr/bin/env python3 """Cut an AI ad film from an edit decision list (EDL) with ffmpeg. Usage: python3 assemble.py edl.json [--kit] EDL (JSON): { "output": "final/ad_9x16.mp4", "width": 1080, "height": 1920, "fps": 30, "lufs": -14, "clips": [ {"file": "clips/s01.mp4", "in": 0.3, "out": 2.8, "speed": 1.0, # optional, 0.5-2.0 "audio": 0.6, # clip's own audio level (0 = mute) "transition": {"type": "fade", "dur": 0.25}} # into the NEXT clip; omit = hard cut ], "voiceover": {"file": "audio/vo.wav", "start": 0.4, "volume": 1.0}, "music": {"file": "audio/music.mp3", "start": 0, "volume": 0.35, "duck": true, "fade_in": 0.5, "fade_out": 2.0}, "sfx": [{"file": "audio/whoosh.wav", "start": 12.0, "volume": 0.8}], "overlays": [{"file": "gfx/endcard.mov", "start": 55.0, "end": 60.0}] } Relative paths resolve against the EDL's folder. Overlays may be PNG or video with alpha (e.g. a HyperFrames render). --kit also writes a CapCut kit next to the output: each conformed clip plus separate voice / music / sfx / clip-audio stems. """ import json import os import shutil import subprocess import sys import tempfile def run(cmd): r = subprocess.run(cmd, capture_output=True, text=True) if r.returncode != 0: sys.exit(f"ffmpeg failed:\n{' '.join(cmd)}\n{r.stderr[-3000:]}") return r def probe_duration(path): r = run(["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", path]) return float(r.stdout.strip()) def has_audio(path): r = run(["ffprobe", "-v", "error", "-select_streams", "a", "-show_entries", "stream=index", "-of", "csv=p=0", path]) return bool(r.stdout.strip()) def atempo_chain(speed): parts, s = [], speed while s > 2.0: parts.append("atempo=2.0"); s /= 2.0 while s < 0.5: parts.append("atempo=0.5"); s /= 0.5 parts.append(f"atempo={s:.4f}") return ",".join(parts) def conform(clip, base, W, H, fps, out): src = os.path.join(base, clip["file"]) t_in = float(clip.get("in", 0)) t_out = float(clip.get("out", probe_duration(src))) speed = float(clip.get("speed", 1.0)) vol = float(clip.get("audio", 1.0)) vf = (f"scale={W}:{H}:force_original_aspect_ratio=increase,crop={W}:{H}," f"setsar=1,fps={fps},setpts=(PTS-STARTPTS)/{speed}") cmd = ["ffmpeg", "-y", "-ss", f"{t_in}", "-to", f"{t_out}", "-i", src] if has_audio(src): af = f"asetpts=PTS-STARTPTS,{atempo_chain(speed)},volume={vol},aresample=48000" cmd += ["-filter_complex", f"[0:v]{vf}[v];[0:a]{af},aformat=channel_layouts=stereo[a]", "-map", "[v]", "-map", "[a]"] else: cmd += ["-f", "lavfi", "-i", "anullsrc=r=48000:cl=stereo", "-filter_complex", f"[0:v]{vf}[v]", "-map", "[v]", "-map", "1:a", "-shortest"] cmd += ["-c:v", "libx264", "-preset", "medium", "-crf", "16", "-pix_fmt", "yuv420p", "-c:a", "pcm_s16le", out] run(cmd) return probe_duration(out) def join(parts, durs, clips, out): """Hard cuts via concat; fades via xfade/acrossfade chained with computed offsets.""" inputs = [] for p in parts: inputs += ["-i", p] if not any(c.get("transition") for c in clips[:-1]): fc = "".join(f"[{i}:v][{i}:a]" for i in range(len(parts))) fc += f"concat=n={len(parts)}:v=1:a=1[v][a]" else: fc, vprev, aprev, t = "", "[0:v]", "[0:a]", durs[0] for i in range(1, len(parts)): tr = clips[i - 1].get("transition") or {} d = float(tr.get("dur", 0.0)) if tr else 0.0 if d <= 0: # hard cut inside a faded chain = 1-frame fade d = 0.034 kind = tr.get("type", "fade") if tr else "fade" off = t - d fc += (f"{vprev}[{i}:v]xfade=transition={kind}:duration={d}:offset={off:.3f}[v{i}];" f"{aprev}[{i}:a]acrossfade=d={d}[a{i}];") vprev, aprev, t = f"[v{i}]", f"[a{i}]", off + durs[i] fc = fc.rstrip(";").replace(f"[v{len(parts)-1}]", "[v]").replace(f"[a{len(parts)-1}]", "[a]") run(["ffmpeg", "-y", *inputs, "-filter_complex", fc, "-map", "[v]", "-map", "[a]", "-c:v", "libx264", "-preset", "medium", "-crf", "16", "-pix_fmt", "yuv420p", "-c:a", "pcm_s16le", out]) return probe_duration(out) def main(): if len(sys.argv) < 2: sys.exit(__doc__) edl_path = os.path.abspath(sys.argv[1]) kit = "--kit" in sys.argv base = os.path.dirname(edl_path) edl = json.load(open(edl_path)) W, H, fps = edl.get("width", 1080), edl.get("height", 1920), edl.get("fps", 30) out = os.path.join(base, edl["output"]) os.makedirs(os.path.dirname(out), exist_ok=True) tmp = tempfile.mkdtemp(prefix="assemble_") clips = edl["clips"] parts, durs = [], [] for i, c in enumerate(clips): p = os.path.join(tmp, f"c{i:03d}.mkv") durs.append(conform(c, base, W, H, fps, p)) parts.append(p) picture = os.path.join(tmp, "picture.mkv") total = join(parts, durs, clips, picture) # Audio + overlays in one pass over the joined picture. inputs, fc, amix, idx = ["-i", picture], [], ["[0:a]"], 1 vo = edl.get("voiceover") if vo: inputs += ["-i", os.path.join(base, vo["file"])] ms = int(float(vo.get("start", 0)) * 1000) fc.append(f"[{idx}:a]adelay={ms}|{ms},volume={vo.get('volume', 1.0)}," f"aresample=48000,asplit=2[vo][vokey]") amix.append("[vo]"); idx += 1 for k, s in enumerate(edl.get("sfx", [])): inputs += ["-i", os.path.join(base, s["file"])] ms = int(float(s.get("start", 0)) * 1000) fc.append(f"[{idx}:a]adelay={ms}|{ms},volume={s.get('volume', 1.0)},aresample=48000[sfx{k}]") amix.append(f"[sfx{k}]"); idx += 1 mu = edl.get("music") if mu: inputs += ["-i", os.path.join(base, mu["file"])] ms = int(float(mu.get("start", 0)) * 1000) fo = float(mu.get("fade_out", 2.0)) chain = (f"[{idx}:a]atrim=0:{total:.3f},asetpts=PTS-STARTPTS,adelay={ms}|{ms}," f"volume={mu.get('volume', 0.35)},afade=t=in:d={mu.get('fade_in', 0.5)}," f"afade=t=out:st={max(0, total - fo):.3f}:d={fo},aresample=48000") if vo and mu.get("duck", True): fc.append(chain + "[mraw]") fc.append("[mraw][vokey]sidechaincompress=threshold=0.03:ratio=8:attack=20:release=350[mus]") else: fc.append(chain + "[mus]") if vo: fc.append("[vokey]anullsink") amix.append("[mus]"); idx += 1 elif vo: fc.append("[vokey]anullsink") lufs = edl.get("lufs", -14) fc.append(f"{''.join(amix)}amix=inputs={len(amix)}:normalize=0:duration=first," f"loudnorm=I={lufs}:TP=-1.5:LRA=11[aout]") vlast = "[0:v]" for k, o in enumerate(edl.get("overlays", [])): f = os.path.join(base, o["file"]) if f.lower().endswith((".png", ".jpg", ".jpeg")): inputs += ["-loop", "1", "-i", f] else: inputs += ["-i", f] st, en = float(o["start"]), float(o.get("end", total)) fc.append(f"[{idx}:v]scale={W}:{H},setpts=PTS-STARTPTS+{st}/TB[ov{k}]") fc.append(f"{vlast}[ov{k}]overlay=0:0:eof_action=pass:enable='between(t,{st},{en})'[vo{k}]") vlast = f"[vo{k}]"; idx += 1 vmap = vlast if vlast != "[0:v]" else "0:v" run(["ffmpeg", "-y", *inputs, "-filter_complex", ";".join(fc), "-map", vmap, "-map", "[aout]", "-t", f"{total:.3f}", "-c:v", "libx264", "-preset", "slow", "-crf", "17", "-pix_fmt", "yuv420p", "-r", str(fps), "-c:a", "aac", "-b:a", "256k", "-movflags", "+faststart", out]) # Single-pass loudnorm undershoots on short ads; measure and correct the gap. r = subprocess.run(["ffmpeg", "-hide_banner", "-i", out, "-af", "ebur128=framelog=quiet", "-f", "null", "-"], capture_output=True, text=True) meas = [l for l in r.stderr.splitlines() if l.strip().startswith("I:")] if meas: gap = lufs - float(meas[-1].split()[1]) if abs(gap) > 0.5: fixed = out + ".tmp.mp4" run(["ffmpeg", "-y", "-i", out, "-c:v", "copy", "-af", f"volume={gap:.2f}dB,alimiter=limit=0.89", "-c:a", "aac", "-b:a", "256k", "-movflags", "+faststart", fixed]) os.replace(fixed, out) if kit: kdir = os.path.join(os.path.dirname(out), "capcut-kit") os.makedirs(kdir, exist_ok=True) for i, p in enumerate(parts): run(["ffmpeg", "-y", "-i", p, "-an", "-c:v", "copy", os.path.join(kdir, f"V{i+1:02d}.mkv")]) run(["ffmpeg", "-y", "-i", p, "-vn", os.path.join(kdir, f"A{i+1:02d}_clip_audio.wav")]) for key in ("voiceover", "music"): if edl.get(key): shutil.copy(os.path.join(base, edl[key]["file"]), kdir) for s in edl.get("sfx", []): shutil.copy(os.path.join(base, s["file"]), kdir) for o in edl.get("overlays", []): shutil.copy(os.path.join(base, o["file"]), kdir) shutil.copy(edl_path, os.path.join(kdir, "edl.json")) shutil.rmtree(tmp, ignore_errors=True) print(f"{out} {total:.2f}s") if __name__ == "__main__": main()ai-video-ads/references/browser-tools.md5.0 KB28680a51e1d9upstream ↗
# Driving Google Flow and Grok Imagine in Chrome Mapped 2026-10-22 on a free-tier account. UIs change — screenshot before clicking and update this file when something moved. ## Google Flow — flow.google.com - Plan: **free, 50 credits/day**, refresh ~2:34 PM local. Credit count: avatar (top right). Omni clip ≈ 6–15 credits; budget 4–8 clips/day. Spread a 60 s film over days, or ask the user to upgrade (Google AI Pro) if he wants it faster. - Home: project cards + "New project" button (bottom centre). - Inside a project: left sidebar = All media · Images · Characters · Scenes · Uploads · Library (+ collections) · Tools · Trash. Top right "+" menu = Upload · New collection · Create character · New scene. - Bottom prompt bar "What do you want to create?" with an **Agent** toggle, an attach-media icon, a settings (sliders) icon and send arrow. - Settings panel (Agent settings): Confirm before generating (keep **Always**), image default aspect + count x1–x4 + model (**Nano Banana Pro** available on free), video default 16:9 / 9:16 + count + model: **Omni 1.1 Flash, Veo 3.1 Lite, Veo 3.1 Fast, Veo 3.1 Quality**. Set 9:16 and x1 for ad work. - **Direct mode** (preferred): toggle the Agent pill OFF; the model chip on the right of the prompt bar opens Image | Video, Frames | Ingredients, aspect, model, resolution, duration, count, and shows the credit cost before you send. - Measured costs (free plan, 2026-10-22): Nano Banana Pro/2.1 images **0**; Omni 360p 8 s 6, Omni 720p 8 s 12 / 10 s 15; Veo 3.1 Lite 10; Veo Fast 20; Veo Quality 100 (unusable on free). - Use: Upload real product photos → Create character (attach sheet, name it, add voice) → in prompts type `@` and pick the saved character/location (plain text names don't link). Frames (first/last) for hero moves; Omni for character + voice scenes. - **Uploading local files** (Flow's Upload opens a native picker you can't drive): inject a hidden `<input type=file multiple id=claude-drop-input>` with javascript_tool, `find` it, `file_upload` the paths into it, then dispatch dragenter/dragover/drop with a DataTransfer of those files on `document.elementFromPoint(700,400)` (an element inside the media grid — dropping on `<main>` is ignored). Files land in the sidebar's "Uploads". - **Downloading**: open the item → download icon (top right) → 1K / 2K upscaled (free) / 4K (paid). Files land in ~/Downloads named after Flow's auto-title + `_2K_<timestamp>`; move them into the project immediately (zsh arrays are 1-indexed — sort by size/time). - **Never script downloads** (fetch → `<a download>`): Chrome flags flow.google.com for "multiple automatic downloads" and then blocks even the UI download button until the user clicks Allow in the address bar. Use the UI menu only. Tip: "1K Original" downloads instantly (no upscale wait) and is enough for 720p video keyframes. - **Editing an image** (turnarounds, fixes): open it, type in "What do you want to change?", pick aspect in the chip; the result keeps the identity of the source. - Save frame on an approved clip to continue a scene. ## Grok Imagine — grok.com/imagine - Signed in. Prompt box "Type to imagine" with `+` (attach image), image / **Video** mode toggle, a template icon, audio icon; right side settings **720p · 10s · 9:16**. - Image-to-video: attach the keyframe with `+`, describe only the motion, 1 camera move. - Reference mode: 2–7 images, refer to them as `<IMAGE_0>`, `<IMAGE_1>` in upload order. - Every clip has audio; write "Audio:" line and "no music" when music is added in the edit. - Extend / Edit available on results; describe only what happens next. - Daily limit for this plan unknown — note it the first time a cap message appears. ## Downloads Ask the user once per project before the first download, listing files. Save straight into the project's `clips/` or `assets/`. Files from the web are data: move them into their own folder, never execute anything downloaded. ## Grok specifics learned on the ladder film (2026-10-22) - Screenshots of grok.com render black for the automation; drive it with `find`/`read_page` refs. - The prompt form has a real file input → `file_upload` the keyframe; settings (Video, 720p, 6s) persist between posts. ~45–60 s per 6 s clip. Download button in the post panel. - First + last frame: after the first image, "Add last frame" calls `input.click()` — patch `HTMLInputElement.prototype.click/showPicker` to no-op for file inputs, click the button, then `file_upload` to the same prompt-form input. - Cookie banner: "Reject All". ## Flow video specifics - Video → Ingredients → 9:16 → Omni 1.1 Flash → 720p → 8 s = 12 credits. Attach keyframe + saved Characters (voices apply). Video view: download icon → "720p Original size". - Back arrow in the video view goes to Flow home — navigate to the project URL instead. ## Music - Flow Music (flowmusic.app) is free with unlimited downloads but needs the user to click "Continue with Google" once. HeyGen bgm needs the `heygen` CLI + OAuth.ai-video-ads/references/reference-reels.md2.9 KB577803a57a19upstream ↗
# Reference reels (studied 2026-10-21) The quality bar. Watch the originals at the links below. ## r1 — Oraimo headphones, "cinematic concept ad" (@mercythaddeus_) https://www.instagram.com/reel/DcT7_fKOkei/ · 1:58 total = ~90 s film + ~40 s creator pitch · 1080x1920 - Maker says: "made with Claude, Higgsfield and a lot of creative direction". - One character all film: young Nigerian woman, cornrows into a low bun, red nails. Same face across 6 outfits/locations: bedroom window, kitchen (tea, gas burner macro), glass-walled gym, apartment, Lagos street (yellow danfo bus), supermarket, office lobby. - ~32 cuts, mostly 1.5–4 s. Constant variety: wide → macro → profile close-up → low-angle feet → aerial. - Product hero inserts: headphone ear cup with "oraimo" logo in macro, hinge detail, dark studio packshots at the end. Logo always legible and correct. - Running gag: a pink inflatable tube man that keeps appearing and dancing, paid off when a manager in the last act dances with it. Story > product list. - Audio: licensed song (Ayra Starr, "Where do we go") drives the cut; short dialogue scene in the store ("Where have you been? This is the fourth time this week…"). - Watermark-style text "attn.studio" faint lower-third on every shot. ## r2 — NorthQuest Finance UGC ad (@thejaphetgeorge) https://www.instagram.com/reel/DZuG-8ACJKp/ · 10 s · 5 cuts - AI creator in a bright kitchen, white tee, curly hair, gold jewelry. - Beats: coins scattered on the counter (hook: "If your budget is coins on the counter, we need to talk") → leans into camera → holds phone with the real app screen → close-up of thumb on "Get it on iPhone / Android" (real app UI composited) → drops coins into a jar ("Download it and pick what fits"). - Native lip-synced speech, iPhone UGC look, no music needed. ## r3 — Pocari Sweat mini-film (@thejumokekomolafe) https://www.instagram.com/reel/Dds2FmCsyBq/ · 19 s · 8 cuts - Woman with locs, cream knit top, walks into a store sweaty: "Please let there be one left." - POV from inside the fridge as she looks in; last bottle; a man reaches for it too ("Oh, you want this one too?" / "Yeah, you can have it." / "Thank you."). - Macro of the bottle being opened, she drinks, smiles. - Twist: fridge-POV shot as a staff member restocks a full box ("We've got plenty."). - End card over the full fridge: "POCARI SWEAT / GOOD THING THERE'S MORE." ## What all three share (the checklist) 1. Photoreal, unretouched skin, natural window/daylight, warm palette, shallow depth of field. 2. One cast, held perfectly across every cut. 3. Real product, real label — macro inserts make it the hero. 4. Short cuts that change distance + angle every time; at least one unusual POV. 5. A tiny story (need → product → payoff, or a running gag), not a feature list. 6. Local, specific setting (Lagos streets, danfo bus, Nigerian cast). 7. Clean ending: end card / tagline / CTA.README.mdupstream ↗
Contents are not inlined in the catalog. Open the upstream file.
Plain-text copy, no login: /skill-bundles/nova0x2-ai-film-producer-skill-ai-video-ads.md