research
MAmattpocock/skills288k10,178 new stars in the last 7 days
Clone an existing video ad for a different product or offer. Analyzes the source video's style, pacing, camera work, dialogue, and tone, then adapts and generates a new Seedance 2.0 video customized for the user's product. End-to-end workflow: input video → analysis → adapted prompt → generation → delivery. Use when someone says "clone this ad", "make this ad but for my product", "recreate this video for my brand", or provides a video ad and a product image asking for a similar video.
Clone an existing video ad for a different product or offer. The agent analyzes the source video frame-by-frame, transcribes dialogue, extracts the visual style and beat structure, then generates a new Seedance 2.0 video adapted for the user's product.
How this differs from analyze-video:
prompt-library/Before starting, verify:
which ffmpeg || echo "MISSING — run: brew install ffmpeg"
python3 -c "import whisper; print('whisper OK')" 2>/dev/null || echo "MISSING — run: pip3 install openai-whisper"
Both extract-frames.sh and whisper depend on ffmpeg. If missing, install via brew install ffmpeg before proceeding.
Collect from the user:
| Input | Required | Notes |
|---|---|---|
| Source video | yes | The video ad to clone. File path to .mp4, .mov, .webm |
| Product image | recommended | Reference photo of the user's product. Becomes referenceImages / @(img1) in the prompt. Without this, Seedance invents its own product design. |
| Product/offer description | if no image | Text description of the product, its features, target audience, and key selling points. Used to rewrite dialogue and product references. |
| Brand voice | optional | Check MASTER_CONTEXT.md for brand blocks. If empty, ask the user for tone/audience preferences. |
If the user only provides a video and says "clone this for my product," ask them for at least a product image or a text description before proceeding.
Reuse the analyze-video extraction script — do NOT duplicate it.
bash "skills/arcads-external-api/prompting/analyze-video/scripts/extract-frames.sh" \
"<source_video_path>" "/tmp/clone-ad-analysis" <num_frames>
Frame count by duration:
| Source duration | Frames |
|---|---|
| Under 10s | 8 |
| 10–20s | 12 |
| 20–30s | 16 |
| Over 30s | 20 |
Outputs:
frame_001.jpg through frame_NNN.jpgaudio.wav (16 kHz mono, whisper-ready)metadata.txt (duration, resolution, fps, frame count)Read metadata.txt to get the source video duration — you'll need it for step 6.
Use whisper to get the exact dialogue. This is critical — the dialogue pattern is what gets adapted for the user's product.
import whisper
model = whisper.load_model("base")
result = model.transcribe("/tmp/clone-ad-analysis/audio.wav")
Record:
result["segments"])If the video is silent (no speech detected), note that and skip the dialogue adaptation in step 7. The clone will be a visual-style clone only.
Read ALL extracted frames visually. For each frame, note:
Structure and pacing:
Camera and framing:
Edit style:
Dialogue and script structure:
Tone and energy:
Lighting and technical quality:
Product references:
What makes this ad distinctive (2–3 defining traits):
Store this analysis internally — it does NOT get saved as a template file.
Show the user a structured breakdown before proceeding:
📋 Source video analysis
Duration: Xs | Beats: N | Dialogue: Y words | Style: [style name]
Beat map:
[00:00–00:03] HOOK — close-up, excited expression, "opening line"
[00:03–00:07] SHOW — tilts product to camera, "feature call-out"
[00:07–00:10] DEMO — (silent) applies/uses product, close-up on texture
[00:10–00:15] VERDICT — back to camera, "closing line + CTA"
Defining traits:
1. [trait 1]
2. [trait 2]
3. [trait 3]
What transfers to your product:
✅ Beat structure, pacing, camera angles, edit style, tone, energy
✅ Dialogue pattern (adapted for your product)
✅ Lighting and technical quality cues
What gets swapped:
🔄 Product references → your product
🔄 Specific claims → your product's features
🔄 Brand mentions → your brand (if provided)
Proceed with adaptation? (yes / adjust)
Wait for user confirmation before continuing.
Walk through this decision tree:
┌─ Source video ≤ 15s?
│ YES → Single-clip generation
│ NO → Multi-clip split at natural beat boundaries
│ Each clip ≤ 15s (Seedance max)
│ Identify best split points from beat map
│ Use the CHAINED MULTI-CLIP PIPELINE below
│
├─ User provided a product IMAGE?
│ YES → Image-to-video mode (referenceImages with @(img1) in prompt)
│ For multi-clip: use i2v for clip 1 ONLY, then chain v2v for clips 2+
│ NO → Text-only mode (describe product in prompt text only)
│ OR v2v if:
│ - Source video has NO human faces
│ - AND user wants to preserve exact visual style
│ - (v2v with faces → content checker rejection + billed)
│
├─ Source video has person SPEAKING?
│ YES → audioEnabled: true (confirm with user)
│ Dialogue confirmation gate REQUIRED (step 7)
│ NO → audioEnabled: false (or ask user preference)
│ Skip dialogue gate
│
└─ User wants voice clone from source audio?
YES → Upload source audio as referenceAudios
(check audio+image regression: run sanity probe first)
NO → Seedance generates its own voice from text
When the source ad is longer than 15s, use this hybrid i2v→v2v chaining pattern for visual continuity:
Clip 1: i2v mode
- referenceImages: [product image] ← establishes brand fidelity
- audioEnabled: true (if speech)
- Generate → poll → download output
Clip 2: v2v mode
- referenceVideos: [clip 1 output] ← inherits hands, surface, lighting, product
- NO referenceImages (mutually exclusive)
- audioEnabled: true (if speech)
- Upload clip 1 output via fresh presigned URL
- Generate → poll → download output
Clip 3: v2v mode
- referenceVideos: [clip 2 output] ← chain from MOST RECENT clip, not clip 1
- Upload clip 2 output via fresh presigned URL
- Generate → poll → download output
...continue for clips 4+
Critical rules for chaining:
POST /v1/file-upload/get-presigned-url immediately before using it as a reference. Do not reuse filePath values from previous uploads.generated status before uploading it as a reference for the next clip. Do not fire clips in parallel — they must be sequential.ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4 (use absolute paths in the list file).Why chaining works: Seedance v2v inherits the visual style, hands, surface, lighting, and product appearance from the reference video. By chaining clip N → clip N+1, each subsequent clip maintains continuity with the one before it. The first clip's i2v reference image establishes the product identity; v2v propagates it through the series.
Cost note: Clip 1 costs the i2v rate (~0.06/sec, 0.9 cr at 15s). Clips 2+ cost the v2v rate (~0.1/sec, 1.5 cr at 15s). A 3-clip series costs ~0.9 + 1.5 + 1.5 = ~3.9 credits total.
Important constraints to check:
referenceImages and referenceVideos are mutually exclusive — pick one per callaudioEnabled: true + referenceImages may 500 (intermittent server regression) — sanity probe firstreferenceVideos count > 1 fails — only 1 ref video worksTell the user which mode you're using and why.
This is the creative core. Using the analysis from step 3:
Dialogue adaptation (if source has speech):
Visual adaptation:
Prompt composition:
@(img1) token if user provided a product image[00:00], [00:04], etc. for multi-beat sequencesDuration selection:
MANDATORY for any clone with spoken dialogue. Follow the exact format from the main SKILL.md:
📝 Dialogue script (please confirm before I generate)
1. [HOOK] "adapted line matching original pattern"
2. [SHOW] "adapted feature call-out for user's product"
3. [DEMO] (silent beat — physical demonstration, no dialogue)
4. [VERDICT] "adapted closing line / CTA"
Total spoken words: ~N | Target duration: Xs | Fits at natural pace: ✅/❌
Approve this dialogue? (yes / edit / rewrite)
Rules:
Ask the user:
audioEnabled: true / false)
true if source video has speechfalse if source video is silentreferenceAudiosaudioEnabled: true + referenceImages):
audioEnabled: false)Follow the main SKILL.md's mandatory estimation flow:
logs/arcads-api.jsonl for matching model + similar configMASTER_CONTEXT.md rate tableEstimated credit cost:
Seedance 2.0 (15s i2v) × 1 clip × 1 variation = ~0.9 credits
(from logs/arcads-api.jsonl 2026-04-09)
─────────────────────────────────────
Estimated total: ~0.9 credits
⚠️ Estimate only — confirm exact cost in the Arcads platform.
Proceed? (yes/no)
Do NOT generate until the user confirms.
Follow the main SKILL.md session folder checklist:
GET /v1/products → resolve productId (default from MASTER_CONTEXT.md)projectIdPOST /v1/file-upload/get-presigned-url:
fileType: "image/jpeg" → auto-upscale if longest side < 1024pxfileType: "video/mp4"fileType: "audio/mpeg" or appropriate typefilePath values for the generation payloadCompose the CreateVideoDto JSON:
model: "seedance-2.0"productId, projectIdprompt (from step 6)aspectRatio: match source video (9:16 or 16:9)duration: from step 6resolution: 720p (default)audioEnabled: from step 8referenceImages: product image filePath (if i2v mode)referenceVideos: source video filePath (if v2v mode, product-only, no faces)referenceAudios: voice clip filePath (if voice clone)Ask generation count (how many variations? default 1)
Single-clip: Fire N parallel POST /v2/videos/generate calls.
Multi-clip (chained): Fire clips sequentially per the chaining pipeline in step 5.
Each clip depends on the previous clip's output — do not fire in parallel.
Log immediately to logs/arcads-api.jsonl:
{
"timestamp": "...",
"endpoint": "POST /v2/videos/generate",
"model": "seedance-2.0",
"assetId": "...",
"request": { "duration": ..., "resolution": ..., ... },
"response": { "status": "pending", "creditsCharged": ... },
"session": { "folderName": "Arcads API - YYYY-MM-DD", "notes": "clone-ad: ..." }
}
Poll GET /v1/assets/{id} until generated or failed
generated before proceeding to the nextcreditsCharged, generationTimeSec, URLsFor multi-clip: upload each completed clip as a fresh presigned URL reference for the next clip (see chaining pipeline in step 5)
POST /v1/assets/add-to-projectoutputs/clone-ad-tests/ (or a descriptive subfolder)open "outputs/clone-ad-tests/" # macOS
printf "file '%s'\n" "$(pwd)/clip1.mp4" "$(pwd)/clip2.mp4" "$(pwd)/clip3.mp4" > /tmp/stitch-list.txt
ffmpeg -y -f concat -safe 0 -i /tmp/stitch-list.txt -c copy stitched-output.mp4
creditsCharged across all clips/variations)Check reference.md for full details. These are the ones most likely to bite during clone-ad:
| Constraint | Impact |
|---|---|
referenceVideos + referenceImages mutually exclusive | Cannot combine in same request (500) |
| v2v with human faces in reference video | Content checker rejects, credits still charged |
audioEnabled: true + referenceImages regression | May return 500 — sanity probe first |
referenceVideos count > 1 fails | Only 1 reference video accepted despite docs saying 3 |
| Content check bills before checking | Credits charged at create time, not refunded on rejection |
endFrame non-functional on Seedance 2.0 | Do not use |
| Prompt length | 100–260 words (Seedance sweet spot) |
| Duration | 4–15 seconds (continuous integer) |
| Aspect ratio | 9:16 or 16:9 only (no 1:1) |
| Forbidden words | cinematic, professional, stunning, 8k, studio, perfect |
| Error | Recovery |
|---|---|
| Content checker rejects prompt | Do NOT retry same payload. Remove potentially flagged language. Tighten motion descriptions. Check for forbidden words. |
500 on audioEnabled: true + referenceImages | Audio+image regression is active. Fallback options: (a) drop audio, (b) drop image and go text-only, (c) v2v workaround: generate silent i2v first, then run v2v with audio on top using the i2v output as reference video |
| v2v face rejection | Source video has humans — switch to i2v mode with user's product image |
| Prompt too long (> 260 words) | Trim: cut filler from tone direction, compress setting details, shorten consistency anchors. Prioritize beat structure and dialogue. |
| Source video > 15s | Split into clips at natural beat boundaries. Generate each separately. Offer to stitch. |
Generation fails (status: failed) | Check data.error.message. If content-related, rewrite prompt. If server error, wait and retry once. |
.md templates instead of generating)CreateVideoDto schema, polling, constraintsMAmattpocock/skills288k10,178 new stars in the last 7 days
AFaffaan-m/ECC278k4,046 new stars in the last 7 days
GAgarrytan/gstack136k883 new stars in the last 7 days
NEnextlevelbuilder/ui-ux-pro-max-skill135k1,864 new stars in the last 7 days
NEnextlevelbuilder/ui-ux-pro-max-skill135k1,864 new stars in the last 7 days
NEnexu-io/open-design101k1,126 new stars in the last 7 days