- name
- paper-collage-ad-codex
- description
- Complete paper-cut collage advertisement production workflow with local IndexTTS-2 voice cloning, animation, audio mixing, and MP4 quality control
- triggers
- ["create a paper collage advertisement","make a paper-cut style video ad","generate animated collage commercial","produce stop-motion paper ad with voice cloning","build paper collage ad with local TTS","create cutout animation advertisement","make paper craft style video commercial","generate collage ad with IndexTTS voice"]
# Paper Collage Ad for Codex
> Skill by [ara.so](https://ara.so) — Codex Skills collection.
A complete paper-cut/collage advertisement production skill for OpenAI Codex. Handles creative concept, script, storyboard, keyframes, animation, voiceover (including local IndexTTS-2 voice cloning), music, sound effects, compositing, and MP4 quality checking.
## What This Does
This skill guides you through producing 30–60 second paper collage advertisements:
- Extract a visual metaphor from product materials
- Generate script, dialogue, and timecoded storyboard
- Create style-locked paper-cut keyframes using brand assets
- Animate via Seedance, HyperFrames, layered PNG, or FFmpeg
- Generate voiceover using standard TTS or **local IndexTTS-2 MLX** for zero-shot voice cloning (Apple Silicon)
- Add music, paper foley, and action sound effects
- Output H.264/AAC MP4 with stream-level validation
## Installation
### Install the Skill
**Global** (all Codex projects):
```bash
git clone https://github.com/Jane-xiaoer/paper-collage-ad-codex.git \
~/.codex/skills/paper-collage-ad
```
**Project-local**:
```bash
mkdir -p .codex/skills
git clone https://github.com/Jane-xiaoer/paper-collage-ad-codex.git \
.codex/skills/paper-collage-ad
```
Restart Codex or start a new task, then say:
```text
Use paper-collage-ad to create a fun 45-second paper collage ad for this product.
```
### System Dependencies
macOS:
```bash
brew install ffmpeg node
bash ~/.codex/skills/paper-collage-ad/scripts/check-deps.sh
```
FFmpeg and Node.js are required. No API keys needed for static keyframes, layered animation, and final compositing.
## Project Structure
When you start a new ad project, create:
```
<project>/
assets/
brand/ # Logo, product images, color palette
keyframes/ # Generated paper-cut PNG frames
voice-reference/ # reference.wav (6–12s clean single-speaker audio)
voice-model/ # speaker-v2.npz (local voice embedding)
voice-final/ # 01.wav, 02.wav... (scene voiceovers)
music/ # Background music loops
sfx/ # Paper rustle, pop, swish sounds
manifests/
storyboard.json # Timecoded scene descriptions
voice.indextts2.json # Voiceover text + emotion per scene
audio-mix.json # Track volumes, fade, timing
output/
final.mp4 # Deliverable
```
Copy the privacy-safe `.gitignore`:
```bash
cp ~/.codex/skills/paper-collage-ad/examples/project.gitignore <project>/.gitignore
```
This excludes `voice-reference/`, `voice-model/`, `voice-final/`, and `.env`.
## Workflow
### 1. Script & Storyboard
Provide product info and target audience. The skill will generate:
- **Storyboard JSON** with scene descriptions, visual metaphor, timing
- **Dialogue script** with emotion tags
Example `manifests/storyboard.json`:
```json
{
"title": "Morning Rush Coffee Ad",
"duration": 45,
"scenes": [
{
"id": "01",
"start": 0.0,
"end": 8.0,
"visual": "Paper-cut alarm clock explodes into coffee beans",
"voiceover": "Every morning is a battle.",
"emotion": "tense"
},
{
"id": "02",
"start": 8.0,
"end": 18.0,
"visual": "Coffee cup rises like a superhero cape",
"voiceover": "Until Morning Rush Coffee arrives.",
"emotion": "heroic"
}
]
}
```
### 2. Generate Keyframes
Use brand assets and the storyboard to create paper-cut style PNG keyframes.
**Manual** (recommended for brand control):
- Design in Photoshop/Figma, export to `assets/keyframes/01.png`, `02.png`...
**AI-assisted**:
```bash
# Example: use DALL-E or Midjourney to generate, then refine
# Store results in assets/keyframes/
```
Each keyframe should match the scene's visual description.
### 3. Animation
#### Option A: Static Keyframes with Transitions
Simple crossfades via FFmpeg:
```bash
node ~/.codex/skills/paper-collage-ad/scripts/render-keyframe-video.mjs \
--manifest manifests/storyboard.json \
--keyframes assets/keyframes \
--output output/video-base.mp4 \
--fps 30 \
--transition crossfade
```
#### Option B: Layered PNG Animation
For parallax or multi-layer movement:
```bash
# Place layered PNGs in assets/keyframes/01/bg.png, 01/mid.png, 01/fg.png
node ~/.codex/skills/paper-collage-ad/scripts/animate-layers.mjs \
--scene 01 \
--duration 8.0 \
--output output/scene-01.mp4
```
#### Option C: Seedance / HyperFrames (API)
If you have API access:
```bash
export SEEDANCE_API_KEY=your_key_here
node ~/.codex/skills/paper-collage-ad/scripts/animate-seedance.mjs \
--keyframe assets/keyframes/01.png \
--prompt "paper coffee cup rises and rotates" \
--duration 8.0 \
--output output/scene-01.mp4
```
### 4. Voice Clone with IndexTTS-2 MLX (Local)
**Setup** (one-time):
```bash
bash ~/.codex/skills/paper-collage-ad/scripts/setup-indextts2-mlx.sh
```
This downloads models to `~/.local/share/paper-collage-ad/mlx-indextts/models/`.
**Prepare Voice Model** (per speaker):
Place authorized reference audio in `assets/voice-reference/reference.wav` (6–12s, 48kHz mono recommended).
```bash
bash ~/.codex/skills/paper-collage-ad/scripts/prepare-indextts2-voice.sh \
"assets/voice-reference/reference.wav" \
"assets/voice-model/speaker-v2.npz" \
--i-have-permission
```
**Generate Voiceovers**:
Copy and edit the manifest:
```bash
cp ~/.codex/skills/paper-collage-ad/examples/voice-manifest.indextts2.json \
manifests/voice.indextts2.json
```
Example `manifests/voice.indextts2.json`:
```json
{
"speaker": "assets/voice-model/speaker-v2.npz",
"output_dir": "assets/voice-final",
"sample_rate": 48000,
"lines": [
{
"id": "01",
"text": "Every morning is a battle.",
"emotion": "tense",
"speed": 1.0
},
{
"id": "02",
"text": "Until Morning Rush Coffee arrives.",
"emotion": "heroic",
"speed": 1.05
}
]
}
```
Run synthesis:
```bash
node ~/.codex/skills/paper-collage-ad/scripts/narrate-indextts2.mjs \
--manifest manifests/voice.indextts2.json
```
Outputs: `assets/voice-final/01.wav`, `02.wav`...
**Privacy**: Only clone your own voice or voices with explicit written permission. Mark deliverables as "AI-generated voiceover."
### 5. Audio Mixing
Prepare background music and SFX in `assets/music/` and `assets/sfx/`.
Create `manifests/audio-mix.json`:
```json
{
"output": "output/audio-mix.wav",
"sample_rate": 48000,
"tracks": [
{
"type": "music",
"file": "assets/music/upbeat-loop.wav",
"volume": 0.3,
"loop": true
},
{
"type": "voiceover",
"file": "assets/voice-final/01.wav",
"start": 0.5,
"volume": 1.0
},
{
"type": "voiceover",
"file": "assets/voice-final/02.wav",
"start": 8.5,
"volume": 1.0
},
{
"type": "sfx",
"file": "assets/sfx/paper-rustle.wav",
"start": 2.0,
"volume": 0.6
}
]
}
```
Mix:
```bash
node ~/.codex/skills/paper-collage-ad/scripts/mix-audio.mjs \
--manifest manifests/audio-mix.json
```
### 6. Final Composite & QC
Merge video and audio:
```bash
ffmpeg -i output/video-base.mp4 -i output/audio-mix.wav \
-c:v libx264 -preset slow -crf 20 -c:a aac -b:a 192k \
-movflags +faststart output/final.mp4
```
Validate:
```bash
bash ~/.codex/skills/paper-collage-ad/scripts/qc-mp4.sh output/final.mp4
```
Checks:
- H.264 video codec
- AAC audio codec, 48kHz
- Duration matches storyboard
- No stream errors
- Fast-start moov atom for web playback
## Configuration
### Environment Variables
Optional API services (only if you use them):
```bash
# .env (never commit this)
SEEDANCE_API_KEY=sk-...
ELEVENLAB_API_KEY=...
MINIMAX_API_KEY=...
```
Load in Node.js scripts:
```javascript
import dotenv from 'dotenv';
dotenv.config();
const apiKey = process.env.SEEDANCE_API_KEY;
```
### Voice Emotion Tags
IndexTTS-2 supports emotion control. Common tags:
- `neutral`
- `happy`, `excited`
- `sad`, `tense`
- `angry`, `calm`
- `heroic`, `mysterious`
Adjust `emotion` in `voice.indextts2.json` per line.
### Animation Parameters
Layered animation script accepts:
```javascript
// scripts/animate-layers.mjs usage
{
scene: "01",
duration: 8.0,
layers: [
{ file: "bg.png", motion: "static" },
{ file: "mid.png", motion: "pan", speed: 20 },
{ file: "fg.png", motion: "zoom", speed: 1.1 }
]
}
```
## Code Examples
### Programmatic Storyboard Generation
```javascript
// generate-storyboard.mjs
import fs from 'fs';
const product = {
name: "Morning Rush Coffee",
tagline: "Wake up ready",
audience: "busy professionals"
};
const storyboard = {
title: `${product.name} Ad`,
duration: 45,
scenes: [
{
id: "01",
start: 0.0,
end: 8.0,
visual: "Alarm clock explodes into coffee beans",
voiceover: "Every morning is a battle.",
emotion: "tense"
},
{
id: "02",
start: 8.0,
end: 18.0,
visual: "Coffee cup superhero cape",
voiceover: `Until ${product.name} arrives.`,
emotion: "heroic"
},
{
id: "03",
start: 18.0,
end: 28.0,
visual: "Paper commuter runs on coffee steam train",
voiceover: "Now you're unstoppable.",
emotion: "excited"
},
{
id: "04",
start: 28.0,
end: 45.0,
visual: "Product pack with logo, sunburst",
voiceover: `${product.name}. ${product.tagline}.`,
emotion: "confident"
}
]
};
fs.writeFileSync('manifests/storyboard.json', JSON.stringify(storyboard, null, 2));
console.log('✓ Storyboard written');
```
### Custom FFmpeg Transition
```javascript
// scripts/render-keyframe-video.mjs (simplified)
import { execSync } from 'child_process';
import fs from 'fs';
const manifest = JSON.parse(fs.readFileSync('manifests/storyboard.json', 'utf-8'));
const keyframesDir = 'assets/keyframes';
const output = 'output/video-base.mp4';
const fps = 30;
let filterComplex = '';
let inputs = '';
manifest.scenes.forEach((scene, i) => {
const duration = scene.end - scene.start;
const kf = `${keyframesDir}/${scene.id}.png`;
inputs += `-loop 1 -t ${duration} -i ${kf} `;
عرض على GitHub