Claude Skill

render-stopmotion-hand-swatch-cycle

Assemble a stop-motion hand-swatch-cycle product-demo ad from a config — a sequence of still PLATES (one hand swiping a single-barrel cosmetic across a cream skin-patch, the barrel + swatch changing per plate while the hand, background, crop, and lighting stay locked) is PNG→mp4

LLM Mart · 0 points · 3 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download gooseworks-ai-goose-skills-skills_ads_capabilities_render-stopmotion-hand-swatch-cycle-e1592ee.zip · 11 KB
Part of gooseworks-ai/goose-skills — 44 skills

Install

skills CLI npx skills add https://github.com/gooseworks-ai/goose-skills/tree/main/skills/ads/capabilities/render-stopmotion-hand-swatch-cycle
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install gooseworks-ai-goose-skills@llmmart
Git git clone https://github.com/gooseworks-ai/goose-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole gooseworks-ai/goose-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

render-stopmotion-hand-swatch-cycle

Assemble a stop-motion hand-swatch-cycle ad from a config: a fast, tactile product demo where a single hand swipes ONE cosmetic barrel across a cream "skin-patch" test surface, and the shade of the barrel AND the painted swatch stripe changes on every frame while the hand, background, crop, and lighting hold still — cycling the variant family so the viewer self-identifies their match, then a hero-pick payoff and a branded end card. This capability is the FREE, deterministic assembly — the per-plate PNG→mp4 loop encode, the concat-demux, the end-card render, and the music mux.

scripts/config.example.json is the worked example (DIBS Beauty "Pick Your Match", ~16.6s 1080×1920 9:16, ~24 cycle plates + finale beats + a 3s end card); scripts/PIPELINE.md maps every config block to its source step and scripts/README.md documents the free assembly.

Run

This is the FREE, deterministic assembly stage — it spends nothing. The paid inputs are separate capabilities — the master-anchor plate + the per-shade / motion / finale plates + the end-card hero BG (create-image-gpt-image-fal, gpt-image-2 EDIT mode, each plate anchored to the SAME master-anchor — never chained), and the music track (create-music-elevenlabs, or a brand-supplied mp3). Given the ordered plate PNGs + per-plate holds + the end-card hero BG + the brand logo SVG + the music track, render-stopmotion-hand-swatch-cycle loop-encodes each plate at its hold, concat-demuxes with hard cuts into a silent master, appends the HTML-rendered end card, and muxes the music under it → the master. Re-cuts (re-timed holds, a re-ordered cycle, a swapped end card) reuse the existing plates / track and cost $0.

Contract (the free assembly)

  • Still plates, not i2v — held for tuned durations. Each plate is a static PNG loop-encoded (ffmpeg -loop 1 -t <pose_hold_ms>) to 1080×1920 @ 30fps crf18. This is stop-motion — discrete held frames, no camera moves, no character animation. Do not animate the plates.
  • Fast stop-motion cadence, HARD cuts. Motion / half-painted plates hold 150–250ms, per-shade plates ~380ms (or ~1000ms for a slower cycle), hero / bookend beats 1100–1800ms; average ~380ms. Concat-demux the plate mp4s in order with hard cuts (ffmpeg -f concat) — NO dissolves. The frame-swap tactility is the whole point; a crossfade erases it.
  • Concat-demux, not filter_complex. The plates are silent stills, so the concat demuxer over the ordered plate list is correct and cheapest. (filter_complex is only needed when clips carry mismatched audio — these don't.)
  • The music carries it — no VO. A pre-sourced brand instrumental (128–130 BPM works well), volume ≈0.4, fade in/out. Do not add a spoken voiceover or a second bed.
  • End card via Playwright HTML from the real logo SVG — never AI-render brand text. A serif tagline + sans subtitle + the real logo SVG composited over a hero product/swatch BG by an HTML template (Chromium headless), rendered to a silent ~3s clip. A diffusion model garbles a wordmark.
  • Music plays UNDER the end card with a fade tail — no silent tail. Mux the track over the whole video including the end card, fade over the last ~0.5s so the video ends WITH the music.
  • FFmpeg composite, deterministic, FREE. Loop-encode each plate, concat-demux on hard cuts, append the end card, mux the music with a fade tail → a 1080×1920 h264+aac master (~16.6s). No paid calls, no keys (beyond the Playwright/Chromium the end-card render needs).
Files (goose-skills)
  • scripts
    • config.example.json 10.5 KB
      {
        "_comment": "DIBS Beauty 'Pick Your Match' stop-motion hand-swatch-cycle — THE WORKED EXAMPLE. Copy to config.json and edit. A ~16.6s vertical 9:16 stop-motion where a fair hand swipes the Desert Island Duo cream stick across a cream skin-patch on a saturated bubblegum-pink background, cycling through the shade family (~10 shades), exiting frame to reveal all 10 swatches, then returning on the hero pick (shade 3), closing on a DIBS end card. NO voiceover — a pre-sourced music track carries it. Pipeline: (1) ONE gpt-image-2 master-anchor plate (hand + barrel + EMPTY cream patch on pink BG); (2) each shade plate in gpt-image-2 EDIT mode anchored to [master-anchor, shade-swatch, shade-hero] — NEVER chained; (3) motion / half-painted transition plates + finale plates (hand-exits -> all-swatches -> hero-pick); (4) PNG->mp4 loop-encode at each plate's hold, concat-demux -> silent master; (5) Playwright HTML end card + brand music mux. Master 1080x1920 h264+aac, ~16.6s (13.6s body + 3.0s end card). See scripts/PIPELINE.md for the source scripts.",
        "brand_name": "DIBS Beauty",
        "campaign": "Pick Your Match",
        "title": "Find your Desert Island Duo shade",
        "width": 1080,
        "height": 1920,
        "fps": 30,
        "crf": 18,
        "duration_sec": 16.6,
        "aspect_ratio": "9:16",
        "background": {
          "_comment": "Format constants held VERBATIM in EVERY plate prompt so the frame never moves — only the barrel shade + the painted swatch stripe change per plate.",
          "bg_hex": "#F4B3C4",
          "bg_desc": "saturated bubblegum-pink (#F4B3C4) seamless paper background",
          "hand": "single fair-skinned hand (fingers + thumb, palm down, glossy pale-pink long-shaped nails) entering from the bottom edge in the LOWER-LEFT third, holding the Desert Island Duo cream stick by its mid-section (cream-and-black ridged barrel, lowercase 'dibs.' wordmark crisp, cap on)",
          "skin_patch": "a soft round cream-colored 'skin patch' surface (~400px wide) in the UPPER-RIGHT third — a curved warm cream-toned section of clean skin that swatches are tested on, flat, smooth, soft-shadowed, no markings",
          "lighting": "editorial soft daylight, glossy gentle highlights, top-down macro, 9:16 vertical, photorealistic beauty editorial, no text overlay",
          "camera": "top-down editorial macro, LOCKED — no camera move, no zoom, no pan"
        },
        "anchor": {
          "_comment": "The MASTER-ANCHOR plate. EVERY other plate is generated in gpt-image-2 EDIT mode anchored back to THIS plate (plus per-shade swatch + hero refs) — NEVER chained plate-to-plate. Source: plates-v3.json `v2-p01`.",
          "id": "master-anchor",
          "out": "assets/plates-v3/v2-p01-hand-anchor.png",
          "hero_ref": "source/product-photos/did-shade-03-hero.png",
          "pose_hold_ms": 1600,
          "prompt": "Top-down editorial macro on a saturated bubblegum-pink (#F4B3C4) seamless paper background. In the LOWER-LEFT third, a single fair-skinned hand enters from the bottom holding a Desert Island Duo cream stick by its mid-section (cream-and-black ridged barrel, lowercase 'dibs.' wordmark crisp, cap on, blush-pink tip toward upper-right). In the UPPER-RIGHT third, a soft round cream-colored 'skin patch' (~400px wide, flat, smooth, soft-shadowed, no markings) — the surface swatches are tested on. Editorial soft daylight, glossy highlights. 9:16 vertical. Photorealistic beauty editorial. No text overlay."
        },
        "plate_engine": {
          "_comment": "All plates + the end-card BG are gpt-image-2 via fal. EDIT mode: each shade / motion / finale plate passes the master-anchor (`v2-p01-hand-anchor.png`) as the first EDIT anchor so the hand + crop + BG stay frozen; shade plates ALSO pass that variant's real swatch + hero refs. NEVER pass a prior plate as the anchor.",
          "provider": "fal",
          "model": "gpt-image-2",
          "mode": "edit",
          "aspect_ratio": "9:16",
          "always_anchor_master": true,
          "never_chain": true,
          "batch_size": 4
        },
        "cadence": {
          "_comment": "DIBS v3 holds: half-painted / mid-swipe motion plates ~180ms; per-shade plates ~380ms (v3 stretched some to ~1000ms for a slower, more scannable cycle); the anchor + finale hero beats 1100-1800ms. HARD cuts between plates. Average ~380ms hold. 27 plate clips across the run.",
          "motion_hold_ms": [150, 250],
          "shade_hold_ms": 380,
          "shade_hold_ms_slow": 1000,
          "hero_hold_ms": [1100, 1800],
          "cut_type": "hard"
        },
        "plates": [
          { "id": "master-anchor", "beat_id": "hand-anchor-empty", "phase": "intro", "variant_slot": "none", "pose_hold_ms": 1600, "cut_type": "hard", "anchors": ["source/product-photos/did-shade-03-hero.png"], "prompt": "MASTER-ANCHOR — hand holding the barrel in the lower-left, EMPTY cream skin-patch in the upper-right, on the bubblegum-pink BG. See config.anchor.prompt. (plates-v3.json v2-p01)" },
          { "id": "empty-swipe-demo", "beat_id": "empty-swipe-demo", "phase": "intro", "variant_slot": "none", "pose_hold_ms": 280, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png"], "prompt": "Same locked frame. The hand extends slightly toward the skin-patch, the barrel tip hovering ~30mm above the patch (about to swipe). No swatch yet. Preview gesture. (plates-v3.json v3-empty-swipe-demo)" },
          { "id": "shade-01", "beat_id": "swatch-shade-01", "phase": "cycle", "variant_slot": "shade", "cycle_index": 1, "pose_hold_ms": 380, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png", "source/swatches/did-shade-01-swatch.jpg", "source/product-photos/did-shade-01-hero.png"], "prompt": "Same locked frame. NEW: a thick painted swatch stripe in SHADE 1 (very fair cool-pink rose cream) swiped horizontally across the center of the cream skin-patch. The hand now holds the SHADE 1 barrel. Only the shade changed. (plates-v3.json v2-p02)" },
          { "id": "swipe-01", "beat_id": "half-painted-015", "phase": "cycle", "variant_slot": "shade", "pose_hold_ms": 180, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png"], "prompt": "Same locked frame, captured MID-SWIPE — the barrel tip touches the patch, the shade 1.5 fresh swatch about half-painted, slight diagonal hand motion. Transition plate. (plates-v3.json v33-swipe-01)" },
          { "id": "shade-015", "beat_id": "swatch-shade-015", "phase": "cycle", "variant_slot": "shade", "cycle_index": 2, "pose_hold_ms": 380, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png", "source/swatches/did-shade-015-swatch.jpg", "source/product-photos/did-shade-015-hero.png"], "prompt": "Same locked frame. The swatch on the patch is REPLACED with SHADE 1.5 (warmer-fair pink); the hand holds the SHADE 1.5 barrel. Same crop, same light — only the shade changed. (plates-v3.json v2-p03)" },
          { "id": "shade-N", "beat_id": "swatch-shade-N", "phase": "cycle", "variant_slot": "shade", "cycle_index": 99, "pose_hold_ms": 380, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png", "source/swatches/did-shade-N-swatch.jpg", "source/product-photos/did-shade-N-hero.png"], "prompt": "Repeat one {shade plate + half-painted-transition} pair per shade in the family (DIBS ran ~10 shades: 01, 015, 02, 025, 03, 04, 05, 055, 06, 07 → ~24 cycle plates). Same locked frame throughout, each shade EDIT-anchored to the master-anchor + its own swatch + hero. (plates-v3.json v2-p04…v2-p11 + v33-swipe-*)" },
          { "id": "hand-exits", "beat_id": "hand-exits-reveal", "phase": "finale", "variant_slot": "none", "pose_hold_ms": 1200, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png", "source/swatches/did-all-shades-family.jpg"], "prompt": "Same locked frame, but the HAND EXITS the frame, revealing ALL 10 painted swatches stacked on the skin-patch. Grounded on the all-shades family reference. (plates-v3.json v3-hand-exits)" },
          { "id": "all-swatches", "beat_id": "all-swatches-reveal", "phase": "finale", "variant_slot": "none", "pose_hold_ms": 1400, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png", "source/swatches/did-all-shades-family.jpg"], "prompt": "The full 10-swatch family on the patch, no hand — the 'here's everything' reveal beat. Holds so the viewer scans for their match. (plates-v3.json v33-finale-shade-3-tilt)" },
          { "id": "hero-pick", "beat_id": "hero-pick-finale", "phase": "finale", "variant_slot": "shade", "pose_hold_ms": 1800, "cut_type": "hard", "anchors": ["assets/plates-v3/v2-p01-hand-anchor.png", "source/product-photos/did-shade-03-hero.png"], "prompt": "The hand RETURNS holding the HERO pick (SHADE 3), the other 9 swatches still visible underneath. The payoff — 'this one is your match'. Hero hold. (plates-v3.json v3-hero-pick-shade-3 / v33-finale-shade-3-macro)" }
        ],
        "end_card": {
          "_comment": "A DIBS end card: a gpt-image-2 hero BG (endcard-bgs/match-hero.png) + a Playwright render of end-card-template-v3.html (serif tagline + sans subtitle + the DIBS logo SVG) — NEVER AI-rendered text. Holds 3.0s WITH the music still playing under it, fade at the tail (no silent tail).",
          "engine": "gpt-image-2-bg + playwright-html",
          "bg_image": "assets/endcard-bgs/match-hero.png",
          "template": "working/end-card-template-v3.html",
          "logo_svg": "source/dibs-logo-black.svg",
          "tagline": "Pick your match.",
          "subtitle": "Desert Island Duo · dibsbeauty.com",
          "hold_sec": 3.0,
          "audio_fade_out_sec": 0.5
        },
        "music": {
          "_comment": "Pre-sourced DIBS brand track (dibs-on-me-4.mp3, ~128 BPM instrumental). Volume 0.4, fade in/out. NO VO. `source` = generate would call create-music-elevenlabs music_v1 from `prompt` (no artist names — ElevenLabs ToS filter).",
          "source": "brand_supplied",
          "provider": "elevenlabs",
          "model": "music_v1",
          "track": "clients/dibsbeauty/music/dibs-on-me-4.mp3",
          "prompt": "Upbeat, bright, playful instrumental pop, ~128 BPM, light percussion, clean modern beauty-brand energy. No vocals.",
          "volume": 0.4,
          "fade_in_sec": 0.3,
          "fade_out_sec": 0.5
        },
        "audio_mix": {
          "_comment": "The music is the full bed — no VO to duck under. It plays UNDER the end card and fades over the tail, so the video ends WITH the music — no trailing silence.",
          "duck_under_vo": false,
          "audio_over_end_card": true,
          "audio_fade_out_sec": 0.5,
          "body_end_s": 13.6,
          "master_duration_s": 16.6
        },
        "post_production": {
          "music": { "default": "on", "note": "the pre-sourced dibs-on-me-4 track IS the bed (no VO), volume 0.4, fade in/out" },
          "captions": { "default": "off", "note": "the swatch cycle reads visually; on-screen type is only the end-card tagline/subtitle" },
          "end_card": { "default": "on", "note": "hero-BG + HTML-template card (serif 'Pick your match.' + sans subtitle + DIBS logo SVG), music under it, fade tail (no silent tail)" }
        }
      }
      
    • PIPELINE.md 5.5 KB
      # Pipeline — stop-motion hand-swatch-cycle
      
      How `config.example.json` maps to the real production steps. This capability ships a **config + this
      map**, not a bundled runner: the worked example (DIBS Beauty "Pick Your Match") was produced by the
      shared stop-motion template scripts plus a per-project plate spec — `generate_plates.py`,
      `build_video.py`, `render_endcard.py`, `finalize_video.py` / `add_endcard_and_music.py` — driven by
      a plate spec (`plates-v3.json`). Reference those directly, or drive the whole run via the video
      orchestrator.
      
      The steps run **in order** because each depends on the last: the master-anchor plate sets the locked
      frame, every shade / motion / finale plate is EDIT-anchored back to it, the plates set the hold
      cadence, the plate mp4s concat into a silent master, and the end card + music close it.
      
      ## Field → source-script map
      
      | Config field | Phase | Source step / script | Paid? |
      |---|---|---|---|
      | `anchor`, `background`, `plate_engine` | 1 Master-anchor | `generate_plates.py` → `gpt-image-2` hand + barrel + EMPTY cream-patch on the brand BG (`plates-v3.json` `v2-p01`) | **PAID** |
      | `plates[].prompt`, `plates[].anchors` (shade) | 2 Shade plates | `generate_plates.py` → `gpt-image-2` EDIT, each anchored to `[master-anchor, shade-swatch, shade-hero]` | **PAID** |
      | `plates[].prompt` (half-painted / motion) | 2 Motion plates | `generate_plates.py` → `gpt-image-2` EDIT mid-swipe plates, anchored to the master-anchor only | **PAID** |
      | `plates[]` (hand-exits / all-swatches / hero-pick) | 3 Finale | `generate_plates.py` → `gpt-image-2` EDIT anchored to master-anchor + the all-variants family ref | **PAID** |
      | `plates[].pose_hold_ms`, `.cut_type`, `cadence` | 4 Encode | `build_video.py` PNG→mp4 loop encode (`-loop 1 -t <hold>`, scale/crop 1080×1920 @ 30fps crf18) | free |
      | assembly (concat) | 4 Assemble | `build_video.py` concat-demuxer over the ordered plate mp4s → silent master | free |
      | `end_card` | 5 End card | `render_endcard.py` → `gpt-image-2` hero BG + Playwright HTML template render → 3s clip | **PAID** (BG) + free (render) |
      | `music`, `audio_mix` | 5 Music | `finalize_video.py` / `add_endcard_and_music.py` → append end card + mux the brand track (vol 0.4, fade) → the master | free (track pre-sourced) |
      
      ## 1. Master-anchor plate → `gpt-image-2`  (config: `anchor`, `background`, `plate_engine`)  [PAID]
      
      **Generate the master-anchor FIRST — it locks the frame.** One `gpt-image-2` render: the fair hand
      in the lower-left third holding the barrel, the EMPTY cream skin-patch in the upper-right third, on
      the saturated brand background, grounded on a product-hero ref. The `background.hand` + `.skin_patch`
      + `.lighting` + `.camera` constants are held **verbatim** here and in every subsequent plate so the
      frame never moves. This plate is the LOCK for the whole cycle.
      
      ## 2. Shade + motion plates → `gpt-image-2` EDIT  (config: `plates[]`, `plate_engine`)  [PAID]
      
      Per variant, one `gpt-image-2` **EDIT** call anchored to `[master-anchor, that shade's swatch ref,
      that shade's hero ref]`. The prompt changes ONLY the barrel shade + the painted swatch stripe;
      everything else is held verbatim. Interleave the half-painted / mid-swipe motion plates (anchored to
      the master-anchor only). **ANCHOR EVERY PLATE TO THE SAME MASTER-ANCHOR — NEVER chain plate N off
      plate N-1.** Chaining compounds hand / crop / background-hue drift and breaks the locked-frame
      illusion (the format's load-bearing rule). Review all plates before step 4; re-roll any whose hand /
      crop / patch drifted (off the master-anchor).
      
      ## 3. Finale plates → `gpt-image-2` EDIT  (config: `plates[]` phase finale)  [PAID]
      
      The hand-exits plate (the hand leaves frame revealing all N swatches, anchored to the master-anchor +
      the all-variants family ref), the all-swatches reveal, and the hero-pick plate (the hand returns
      holding the chosen variant, other swatches visible). Same lock. This phase also renders the end-card
      hero BG.
      
      ## 4. Encode + assemble → `build_video.py`  (config: `plates[].pose_hold_ms`, `cadence`) [FREE]
      
      Encode each plate PNG→mp4 at its own `pose_hold_ms` (`ffmpeg -loop 1 -t <hold>`, scale/crop to
      1080×1920 @ 30fps crf18) — motion / half-painted plates 150–250ms, per-shade ~380ms (or ~1000ms for a
      slower cycle), hero / bookend beats 1100–1800ms — then concat-**demux** the plate mp4s in order
      (`ffmpeg -f concat`) into the silent master. HARD cuts between plates, no dissolves. DIBS v3 ran 27
      plate clips (15 unique plates, some reused across the cycle). Concat-demux (not `filter_complex`) is
      correct because the plates are silent stills. Free — a re-cut reuses the existing plate PNGs.
      
      ## 5. End card + music → `render_endcard.py` + `finalize_video.py`  (config: `end_card`, `music`, `audio_mix`) [FREE assembly]
      
      - `render_endcard.py`: a `gpt-image-2` hero BG + a Playwright render of the end-card HTML template
        (serif tagline + sans subtitle + the real logo SVG) → a silent ~3s end-card mp4. **Never AI-render
        the tagline / logo** — the HTML template composites the real logo SVG over the hero BG.
      - `finalize_video.py` / `add_endcard_and_music.py`: append the end card after the silent master, mux
        the pre-sourced brand music track (`music.track`, volume 0.4, `music.fade_in_sec` / `.fade_out_sec`)
        OVER the whole video including the end card with a fade at the tail (`audio_over_end_card` — no
        silent tail) → the master (1080×1920, 30fps, h264+aac, ~16.6s).
      
      Re-cuts (new holds, a re-ordered cycle, a swapped end card, a different track) reuse the existing
      plates and cost **$0** — only steps 1–3 + the end-card BG spend.
      
    • README.md 2.9 KB
      # render-stopmotion-hand-swatch-cycle scripts — the FREE assembly
      
      `render-stopmotion-hand-swatch-cycle` is the **deterministic, $0 assembly stage** of the stop-motion
      hand-swatch-cycle format. The paid stages (the master-anchor plate, the N per-shade / motion / finale
      plates, the end-card hero BG, the music track) are separate capabilities —
      `create-image-gpt-image-fal` and `create-music-elevenlabs`. This capability spends nothing: it takes
      the ordered plate PNGs + per-plate holds + the end-card hero BG + the brand logo SVG + the music
      track and stitches the finished master. Re-cuts (re-timed holds, a re-ordered cycle, a swapped end
      card, a different track) reuse the existing plates and cost **$0**.
      
      `config.example.json` is the worked example (DIBS Beauty "Pick Your Match", ~16.6s 1080×1920).
      `PIPELINE.md` maps every config block to its source step. This README documents the FREE assembly
      pieces that `render-stopmotion-hand-swatch-cycle` owns.
      
      ## 1. Still plates — PNG→mp4 loop-encode at each plate's stop-motion hold
      
      Each plate is a static PNG, loop-encoded to a short mp4 at its own `pose_hold_ms` (`ffmpeg -loop 1
      -t <hold>`, scale/crop to 1080×1920 @ 30fps crf18). This is stop-motion — discrete held frames, no
      camera moves, no character animation. The holds set the cadence: fast motion / half-painted plates
      150–250ms, per-shade plates ~380ms (or ~1000ms for a slower, more scannable cycle), hero / bookend
      beats 1100–1800ms. Average ~380ms gives the tactile frame-swap feel.
      
      ## 2. Concat-demux on hard cuts
      
      Concat-**demux** the plate mp4s in order (`ffmpeg -f concat` over the ordered plate list) with HARD
      cuts — no dissolves. The frame-swap tactility is the whole point of stop-motion; a crossfade erases
      it. Concat-demux (not `filter_complex`) is correct because the plates are silent stills with no audio
      to reconcile. DIBS v3 ran 27 plate clips into a ~13.6s silent body master.
      
      ## 3. End card — Playwright HTML from the real logo SVG, no AI text
      
      The end card is a Playwright (Chromium headless) render of an HTML template — a serif tagline + a
      sans subtitle + the real logo SVG composited over a `gpt-image-2` hero product/swatch BG — rendered
      to a silent ~3s clip. The brand text is **never** AI-rendered — a diffusion model garbles a wordmark.
      On macOS pick a font with the em-dash / middle-dot glyph for the subtitle separator.
      
      ## 4. FFmpeg composite + music mux
      
      FFmpeg stitches the master: loop-encode each plate, concat-demux on hard cuts into the silent body
      master, append the end card holding ~3s, then mux the pre-sourced music track (volume ≈0.4, fade
      in/out) OVER the whole video including the end card with a fade at the tail (no silent tail — the
      video ends WITH the music). The music IS the bed — no separate VO. Output is a 1080×1920 h264 + aac
      master (~16.6s). Deterministic, no paid calls, no keys (beyond the Playwright/Chromium the end-card
      render needs).
      
  • tests
    • smoke-test.md 1.4 KB
      # Smoke Test
      
      Given N still plates (a master-anchor hand + barrel + empty cream-patch, then per-shade / motion /
      finale plates with ONE locked hand + crop + background), an end-card hero BG + brand logo SVG, and a
      pre-sourced music track, `render-stopmotion-hand-swatch-cycle` assembles the master: loop-encode each
      plate at its own stop-motion hold, concat-demux with HARD cuts into a silent body master, append a
      Playwright HTML-rendered branded end card, mux the music under it → 1080×1920 h264+aac (~16.6s).
      
      Pass when the assembly runs to a valid MP4 and:
      - each plate is a still held for its `pose_hold_ms` (fast motion 150–250ms, per-shade ~380ms, hero
        1100–1800ms); hard cuts between plates (no crossfades); the ONE locked hand + crop + background
        holds across every cycle plate (no drift);
      - each swatch stripe is the real variant color (grounded on the shade's swatch + hero refs);
      - the end card is a Playwright HTML render (serif tagline + sans subtitle + the real logo SVG over
        the hero BG, no AI-rendered text), the music carrying under it with a fade tail (no silent tail);
      - the music is the entire bed — no separate VO;
      - **no paid call is made** — the master-anchor plate, the shade / motion / finale plates, and the
        end-card BG come from `create-image-gpt-image-fal`, and the track from `create-music-elevenlabs`;
        this assembly is **$0** and a re-cut (re-timed holds, a re-ordered cycle, a swapped end card) reuses
        the existing plates.
      
  • SKILL.md 4.6 KB
    ---
    name: render-stopmotion-hand-swatch-cycle
    description: Assemble a stop-motion hand-swatch-cycle product-demo ad from a config — a sequence of still PLATES (one hand swiping a single-barrel cosmetic across a cream skin-patch, the barrel + swatch changing per plate while the hand, background, crop, and lighting stay locked) is PNG→mp4 loop-encoded at each plate's own stop-motion hold (fast motion frames 150–250ms, per-shade ~380ms, hero beats 1100–1800ms), concat-demuxed with HARD cuts into a silent master, closed on a Playwright HTML-rendered branded end card (serif tagline + sans subtitle + real logo SVG over a hero BG, never AI-rendered text), and muxed with a pre-sourced music track playing under the end card with a fade tail (no VO). This is the FREE deterministic assembly stage (loop-encode + concat-demux + end-card render + music mux); the master-anchor plate, shade plates, and end-card BG come from create-image-gpt-image-fal and the track from create-music-elevenlabs. Use for the stopmotion-hand-swatch-cycle format.
    status: active
    ---
    
    # render-stopmotion-hand-swatch-cycle
    
    Assemble a **stop-motion hand-swatch-cycle** ad from a config: a fast, tactile product demo where a
    single hand swipes ONE cosmetic barrel across a cream "skin-patch" test surface, and the shade of
    the barrel AND the painted swatch stripe changes on every frame while the hand, background, crop,
    and lighting hold still — cycling the variant family so the viewer self-identifies their match, then
    a hero-pick payoff and a branded end card. This capability is the **FREE, deterministic assembly** —
    the per-plate PNG→mp4 loop encode, the concat-demux, the end-card render, and the music mux.
    
    `scripts/config.example.json` is the worked example (DIBS Beauty "Pick Your Match", ~16.6s 1080×1920
    9:16, ~24 cycle plates + finale beats + a 3s end card); `scripts/PIPELINE.md` maps every config
    block to its source step and `scripts/README.md` documents the free assembly.
    
    ## Run
    
    This is the **FREE, deterministic** assembly stage — it spends nothing. The paid inputs are separate
    capabilities — the master-anchor plate + the per-shade / motion / finale plates + the end-card hero
    BG (`create-image-gpt-image-fal`, gpt-image-2 EDIT mode, each plate anchored to the SAME
    master-anchor — never chained), and the music track (`create-music-elevenlabs`, or a brand-supplied
    mp3). Given the ordered plate PNGs + per-plate holds + the end-card hero BG + the brand logo SVG +
    the music track, `render-stopmotion-hand-swatch-cycle` loop-encodes each plate at its hold,
    concat-demuxes with hard cuts into a silent master, appends the HTML-rendered end card, and muxes the
    music under it → the master. Re-cuts (re-timed holds, a re-ordered cycle, a swapped end card) reuse
    the existing plates / track and cost **$0**.
    
    ## Contract (the free assembly)
    
    - **Still plates, not i2v — held for tuned durations.** Each plate is a static PNG loop-encoded
      (`ffmpeg -loop 1 -t <pose_hold_ms>`) to 1080×1920 @ 30fps crf18. This is stop-motion — discrete
      held frames, no camera moves, no character animation. Do not animate the plates.
    - **Fast stop-motion cadence, HARD cuts.** Motion / half-painted plates hold 150–250ms, per-shade
      plates ~380ms (or ~1000ms for a slower cycle), hero / bookend beats 1100–1800ms; average ~380ms.
      Concat-**demux** the plate mp4s in order with hard cuts (`ffmpeg -f concat`) — NO dissolves. The
      frame-swap tactility is the whole point; a crossfade erases it.
    - **Concat-demux, not filter_complex.** The plates are silent stills, so the `concat` demuxer over
      the ordered plate list is correct and cheapest. (`filter_complex` is only needed when clips carry
      mismatched audio — these don't.)
    - **The music carries it — no VO.** A pre-sourced brand instrumental (128–130 BPM works well),
      volume ≈0.4, fade in/out. Do not add a spoken voiceover or a second bed.
    - **End card via Playwright HTML from the real logo SVG — never AI-render brand text.** A serif
      tagline + sans subtitle + the real logo SVG composited over a hero product/swatch BG by an HTML
      template (Chromium headless), rendered to a silent ~3s clip. A diffusion model garbles a wordmark.
    - **Music plays UNDER the end card with a fade tail — no silent tail.** Mux the track over the whole
      video including the end card, fade over the last ~0.5s so the video ends WITH the music.
    - **FFmpeg composite, deterministic, FREE.** Loop-encode each plate, concat-demux on hard cuts,
      append the end card, mux the music with a fade tail → a 1080×1920 h264+aac master (~16.6s). No paid
      calls, no keys (beyond the Playwright/Chromium the end-card render needs).
    
  • skill.meta.json 347 B
    {
      "slug": "render-stopmotion-hand-swatch-cycle",
      "category": "capabilities",
      "domain": "ads",
      "tags": [
        "ads"
      ],
      "installation": {
        "base_command": "npx goose-skills install render-stopmotion-hand-swatch-cycle",
        "supports": [
          "claude",
          "cursor",
          "codex"
        ]
      },
      "requires_skills": [
        "watch"
      ]
    }
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related