SuperAPI AI Directory

create-silent-product-demo

General & other

View repository

Updated 10-15 21:54

About this skill

create-silent-product-demo

Purpose

Produce a shippable 12-20s silent (music-only) product demo Reel using the silent-product-demo archetype from CREATOR_GRAMMAR.md §8. The archetype's defining pattern:

  • One static caption holds the full duration — the hook claim rendered as a bold-tiktok-hook title card. No VO, no karaoke captions, no burned-in CTA.
  • Feature-flash bursts (5-8 hard cuts under 1s) showcase product features in rapid succession, bracketed by holds.
  • One payoff hold — the hero moment (product working, the reveal, the money shot) runs 2–4× the mean shot length.
  • Silence-masked cut hides the biggest edit in a 0.3–0.6s gap in the music.
  • Beat-synced cuts throughout; cut density front-loads into the hook segment.

The molecule supports two footage modes:

  • Generative — scenes generated via create-image-nano-banana-fal + create-video-seedance. Best when no real product footage exists.
  • Conform — existing product footage re-cut via trim-video-clips. Best when the brand has a real shoot or UGC source.

This is CREATOR_GRAMMAR.md Tier 1 (fully reproducible now): the entire editorial layer — cut points, payoff hold, beat-sync, static caption — is AI-reproducible. Only the payoff-hold visual may require Tier 2 i2v if physics is critical.

Inputs

Input Required Notes
hook_caption yes The one sentence that holds on screen. ≤7 words. No URL, no price.
shot_list yes 5-8 scenes describing what the product does. One line per scene: "<shot-size>, <subject>, <action>". The payoff scene is labeled.
footage_mode yes "generative" or "conform".
source_clips conform mode only Paths to raw product footage file(s).
product_reference generative mode Path to a product image. Drives create-image-nano-banana-fal keyframes.
music_path no Path to an existing music track. If omitted, find-music or create-music-elevenlabs is run.
target_duration no, default 15 Target video length in seconds (12-20).
output_dir yes Project directory following the canonical 5-folder layout.

Composed Atoms

  • atoms/audio-editing/extract-beat-grid — analyse the music track and produce beat-grid.json. Required because silent-product-demo is beat_sync: true.
  • atoms/planning/generate-edit-decision-list — consume the shot list + beat-grid and produce a validated edl.json (archetype silent-product-demo, grammar.loop: false). Sets the payoff-hold clip, silence-masked cut, and static-title-card caption.
  • atoms/assembly/render-edl — execute the edl.json into master.mp4. Handles hard-cut concat, audio bed (music + silence beats), and burns the static title card.
  • atoms/music/find-music — source a royalty-free music track when none is provided (preferred: bright/energetic, 100-140 BPM). Used before extract-beat-grid.
  • atoms/music/create-music-elevenlabs — fallback music generation when find-music yields nothing suitable.
  • atoms/image-generation/create-image-nano-banana-fal — render each scene keyframe from a product reference image (generative mode, Tier 1).
  • atoms/video-generation/create-video-seedance — animate each keyframe into a short motion clip (generative mode, Tier 2 — use only when motion specificity is needed; static stills work for feature-flash shots).
  • atoms/editing/trim-video-clips — trim and time-align raw footage clips to EDL target durations (conform mode).
  • atoms/editing/add-zoom-cuts — apply zoom-punch post-motion on feature-flash cuts in the hook segment (optional, recommended for Tier 1 clips).
  • atoms/audio-editing/synthesize-sfx-ffmpeg — add whoosh/tap SFX on feature-flash cut points per the EDL's sfx[] array.
  • atoms/captions/style-captions — confirm the static title card is rendered with the bold-tiktok-hook preset at the correct safe-area position.
  • atoms/review/watch — frame-grounded QC of the final master.

Workflow

Phase 0 — Intake

  1. Read hook_caption and shot_list. Confirm the shot list has 5-8 scenes and one scene is labeled as the payoff (the hero moment).
  2. Confirm footage_mode. If "generative" and no product_reference is provided, STOP and ask.
  3. If "conform", validate every source_clips path exists on disk.
  4. Set target_duration (default 15). Validate it is in the 12-20s range.
  5. Create output_dir with canonical 5-folder structure: source/, assets/, finals/, working/, archive/.

Phase 1 — Music + beat grid

  1. Music selection:
    • If music_path is provided, skip to step 2.
    • Otherwise run find-music with a brief matching the product mood. If find-music returns a suitable track, use it. If not, run create-music-elevenlabs with a prompt derived from the shot list (bright/energetic instrumental, target BPM 100-140, target duration target_duration + 2s).
    • Write the music file to assets/music/track.mp3.
  2. Run extract-beat-grid on the music track:
    python3 skills/atoms/audio-editing/extract-beat-grid/scripts/extract_beats.py \
      --source assets/music/track.mp3 \
      --output-dir working/beat-grid/
    
    Record bpm and verify beats is non-empty. Warn if BPM < 80 or > 180 (unusual for this archetype).
  3. Write working/beat-grid/beat-grid.json path for use in Phase 2.

Phase 2 — Generate edit decision list

  1. Build a scene table JSON at working/scene-table.json:
    [
      { "scene_id": "s01", "description": "<shot-list line 1>", "role": "hook" },
      { "scene_id": "s02", "description": "<shot-list line 2>", "role": "feature" },
      ...
      { "scene_id": "sNN", "description": "<payoff scene>", "role": "payoff-hold" }
    ]
    
    The payoff-hold scene must be positioned in the 60-85% window of target_duration (i.e. roughly target_duration × 0.6 to target_duration × 0.85).
  2. Run generate-edit-decision-list:
    • archetype: "silent-product-demo"
    • source_mode: "generative" or "conform"
    • beat_grid: "working/beat-grid/beat-grid.json"
    • target_duration: <target_duration>
    • output_path: "working/edl.json"
  3. Validate that edl.json passes the validator. Check:
    • Exactly one clip has role: "payoff-hold".
    • grammar.caption_family: "static-title-card".
    • grammar.caption_preset: "bold-tiktok-hook".
    • The caption cue has text == hook_caption and spans 0.0 to meta.target_duration.
    • No karaoke-pop captions (EDL validation rule 7).
    • audio.beat_grid is set to the beat-grid path.
  4. If the validator fails, fix each error and re-run before proceeding.

Phase 3 — Generate or trim scene clips

Generative mode:

For each scene clip listed in edl.json:

  1. Run create-image-nano-banana-fal on the product_reference with the clip's source.spec.description as the style prompt. Save keyframe to assets/keyframes/<id>.png.
  2. If the clip's target_out - target_in > 2.0s and the scene requires visible product motion (pouring, pressing, spraying), run create-video-seedance with the keyframe → short motion clip. Save to assets/clips/<id>.mp4.
  3. For clips ≤ 2.0s or where motion is not required (static display, flat lay, label close-up), use the still image directly — render-edl handles static-image clips.
  4. Apply add-zoom-cuts to feature-flash clips in the hook segment (clips with role: "hook") for a zoom-punch post-motion effect.

Conform mode:

For each scene clip listed in edl.json:

  1. Run trim-video-clips to extract the target range from the source.file at source.in to source.out.
  2. Save trimmed clip to assets/clips/<id>.mp4.
  3. Apply add-zoom-cuts to hook-segment clips as in generative mode.

Phase 4 — Add SFX

For each clip in edl.json that has a non-empty sfx[] array:

  1. Run synthesize-sfx-ffmpeg to generate the whoosh or tap SFX at the specified at timestamps.
  2. SFX are passed to render-edl via the EDL; no manual mixing step needed.

Phase 5 — Render master

Run render-edl:

python3 skills/atoms/assembly/render-edl/scripts/render_edl.py \
  --edl working/edl.json \
  --output finals/master.mp4 \
  --project-dir <output_dir> \
  --crf 18

Verify manifest.json exists alongside master.mp4 with status: pass and clips_rendered paths all resolving on disk.

Phase 6 — Self-QC

Run atoms/review/watch on finals/master.mp4 with the following QC prompt:

"Check: (1) the static hook caption holds full duration without drift; (2) the payoff-hold shot is the longest clip by 2–4× the mean shot length; (3) no karaoke captions appear; (4) the silence-masked cut before the payoff is not jarring; (5) cuts in the hook segment land on beats; (6) the tail decelerates."

Report findings as a timestamp punch list. If critical issues are found, fix and re-render from the appropriate phase.

Decision Rules

DR-1 — Generative vs conform footage choice

Use the CREATOR_GRAMMAR.md §10 tiers:

Footage tier EDL source mode Clip generation approach
Tier 1 (flat lay, label, push-button action) generative Nano Banana still only — no i2v
Tier 2 (product motion, pour, spray) generative Nano Banana still → Seedance i2v
Tier 3 (hands manipulating, liquid physics) conform Real footage is mandatory — AI fails here

Never spend i2v credits on a Tier 1 clip. If the shot description mentions hands, sustained physical manipulation, or liquid physics, switch to conform mode for that clip (hybrid EDL source mode is allowed — see EDL schema §"Source modes").

DR-2 — Payoff hold placement

The payoff-hold clip must be the single longest clip in the timeline. Its duration must be 2.0×–4.0× pacing_curve.mean_shot_len. The rule: if the money shot feels rushed after rendering, extend it — the payoff hold is never wrong if it's the hero moment. Place it in the 60-85% window of the video. Do not place it in the first 50% — the pacing curve front-loads for the hook, not the reward.

DR-3 — Static caption placement

The bold-tiktok-hook caption must:

  • Start at target_in: 0.0 and hold to the last frame.
  • Position in the upper-third (top 25% of the safe area) — not lower-center, which is the default for karaoke-pop. Override the preset's default position if needed.
  • Be ≤7 words (longer text violates the "built sound-off-first" rule).
  • Not appear on the payoff-hold or tail clips if those clips have their own on-screen product text (suppress to avoid two-layer collision per LEARNINGS.md #7).

DR-4 — Music tempo and energy

The music track should match the pacing curve: energetic in the hook/body, building into the payoff drop, with a tail-deceleration after. The EDL's audio.music_drop_s field must be set to the payoff-hold clip's target_in. If find-music returns a track whose drop does not land at the payoff, trim or crossfade the music in the render-edl audio build step.

DR-5 — Beat snapping

For beat_sync: true, every clip boundary in the body segment must snap to a bar boundary within ±150ms. If the pacing calculation lands a clip boundary more than 150ms from any bar, move the boundary to the nearest bar (even if this changes the clip duration by up to 10%). Use the generate-edit-decision-list beat-snapping step (Step 6 in that atom's workflow).

Output

<output_dir>/
├── source/             ← original product footage (conform mode) or reference images
├── assets/
│   ├── music/
│   │   └── track.mp3
│   ├── keyframes/
│   │   └── <id>.png   ← Nano Banana keyframes (generative mode)
│   └── clips/
│       └── <id>.mp4   ← trimmed or generated scene clips
├── working/
│   ├── beat-grid/
│   │   ├── beat-grid.json
│   │   └── manifest.json
│   ├── scene-table.json
│   ├── edl.json
│   └── planning-notes.md
└── finals/
    ├── master.mp4      ← the delivered output
    └── manifest.json

The finals/master.mp4 is the shippable Reel: 9:16, 1080×1920, h264 + AAC, 30fps, 12-20s, with the static title card burned in and no VO track.

Quality Checks

  • finals/master.mp4 exists and is non-zero; ffprobe reports both video and audio streams.
  • Duration of master.mp4 is within ±0.5s of target_duration.
  • Resolution is 1080×1920 (9:16), 30fps.
  • Exactly one clip has role: "payoff-hold" and its duration is 2.0–4.0× manifest.json::pacing_curve.mean_shot_len.
  • The static hook caption spans full duration (0.0 to target_duration); no karaoke-pop captions appear in any frame.
  • Audio track is present; no silent sections longer than 0.7s except the deliberate silence beat before the payoff (allowed: 0.25-0.6s).
  • manifest.json exists with status: pass and all clips_rendered paths resolve on disk.
  • Self-QC punch list from Phase 6 has zero critical issues.
  • For conform mode: every source.file path in edl.json exists.
  • For beat-synced clips: all beat-synced-cut target_in values are within ±50ms of a grid bar boundary in beat-grid.json.

Failure Modes

  • No product reference image provided (generative mode) — cannot run create-image-nano-banana-fal. Request the image before starting Phase 3. Nano Banana requires a visual reference to generate on-brand keyframes.
  • Payoff window too short for the archetype's 2.5× multiplier — the shot list may have too many scenes for the target duration. Remove one body scene or shorten two feature clips. Validate pacing with edl_pacing.py before generation.
  • AI generates Tier 3 footage (hands, liquid physics) — reroll rates are coin-flip at best (LEARNINGS.md #6). Switch to conform mode for that clip immediately rather than burning Seedance credits on retries.
  • Music track has no identifiable beats (BPM < 20 from extract-beat-grid) — ambient drone / atonal tracks don't beat-sync. Replace with a track that has a clear rhythmic pulse.
  • Static caption collides with product text in the payoff-hold clip — two text layers at the same position = both unreadable (LEARNINGS.md #7). Suppress the title card on the payoff clip using notes: "suppress-caption" in the EDL clip, or move the title card to the upper-third only.
  • render-edl reports missing generate-mode clips — one or more assets/clips/<id>.mp4 not generated. Re-run Phase 3 for the missing clips before re-running the renderer.
  • edl_validate.py exits non-zero — do not proceed to rendering. Fix each reported error (contiguity, missing payoff-hold, wrong caption family) and re-run the validator.
  • Music drop does not align with payoff hold — the energy peak lands at the wrong moment. Set audio.music_drop_s explicitly in the EDL, or choose a track whose drop naturally falls in the 60-85% window.