
Videoagent Director
- 453 installs
- 762 repo stars
- Updated July 21, 2026
- pexoai/pexo-skills
videoagent-director is an agent skill that turns a natural-language video brief into a shot storyboard and generates images, video clips, and audio via director.js for developers building automated video production workf
About
videoagent-director (version 1.1.0) in pexoai/pexo-skills acts as an AI creative director that converts a user's idea into a complete storyboard and produces all assets without surfacing prompt engineering details. The workflow infers concept, aspect ratio (9:16, 16:9, or 1:1), tone, and target length (15–60 seconds), shows a compact shot table for one-word approval, then calls director.js once per shot with internal image, video, and audio prompts. Shot counts scale from 3–4 shots for 15–20 seconds up to 7–9 shots for 45–60 seconds, with patterns for brand ads, social reels, and short-film teasers. Audio rules assign music to opening and closing shots, SFX to action beats, and TTS only when narration is requested. Developers reach for videoagent-director when building agent-driven brand videos, social reels, or product ads from a single natural-language brief. No API keys are required because the skill orchestrates existing hosted proxies.
- Shot and scene sequencing orchestration
- Prompt and creative brief structuring
- Multi-agent video pipeline coordination
- Consistency across generated scenes
- Constraint-driven generative direction
Videoagent Director by the numbers
- 453 all-time installs (skills.sh)
- +11 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #419 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/pexoai/pexo-skills --skill videoagent-directorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 453 |
|---|---|
| repo stars | ★ 762 |
| Last updated | July 21, 2026 |
| Repository | pexoai/pexo-skills ↗ |
How do agents produce multi-shot videos from a brief?
Direct multi-step video generation agents through shot planning, scene sequencing, prompts, and creative constraints to produce coherent automated video outputs.
Who is it for?
Developers building agent workflows that generate brand videos, social reels, or short films from natural-language creative briefs.
Skip if: Manual video editors who want frame-by-frame control or teams that need a specific proprietary render farm without agent orchestration.
When should I use this skill?
User wants to make a video, storyboard, scene breakdown, or short clip from a natural-language idea including brand videos and social reels.
What you get
Shot storyboard table, per-shot image and video URLs, audio assets, and a production report with scene breakdown.
- Shot storyboard table
- Per-shot media URLs
- Production report
By the numbers
- Skill version 1.1.0 with director.js CLI per shot
- Shot tables scale from 3–4 shots (15–20s) to 7–9 shots (45–60s)
Files
🎬 VideoAgent Director
Use when: The user wants to produce a video from a natural-language idea — a brand video, short film, social reel, product ad, or any creative concept. Also use for "make a storyboard", "create a scene breakdown", or "produce a short clip about X".
You are the creative director. The user describes what they want. You handle everything — shot planning, prompt writing, asset generation — without asking the user to write any prompts.
---
Your Responsibilities
The user gives you an idea. You do the rest.
- Break the idea into the right number of shots
- Write all image, video, and audio prompts internally (never ask the user to write them)
- Execute each shot via
director.js - Return a clean, visual production report
Never surface prompt details, model names, or technical parameters to the user unless explicitly asked.
---
Workflow
Step 1 — Understand the brief (one pass)
From the user's message, infer:
- Concept — What is the video about?
- Format — Vertical (9:16) for social/mobile, landscape (16:9) for film/desktop, square (1:1) for feed. Default to 16:9 if unclear.
- Tone — Cinematic, energetic, calm, playful, corporate, dramatic
- Length — Short (15–20 s), standard (30 s), long (45–60 s). Default to 30 s.
If any of these is truly ambiguous, ask one clarifying question only. Otherwise, proceed.
Step 2 — Show a one-line storyboard for quick confirmation
Plan all shots internally, then show the user only a compact table — no prompts, no technical details:
🎬 **[Title]** · [N] shots · [format] · ~[duration]s
| # | Scene | Audio |
|---|-------|-------|
| 1 | Rainy street, wide establishing | music |
| 2 | Neon sign reflection in puddle | rain SFX |
| 3 | Person with umbrella, tracking | city ambience |
| 4 | Fade to black on neon glow | music |
Looks good? I'll start generating.Wait for a single word of approval (e.g. "yes", "go", "ok", "好的", or any positive reply) before proceeding.
Step 3 — Execute shot by shot
Call director.js once per shot after user confirms.
node {baseDir}/tools/director.js \
--shot-id <n> \
--image-prompt "<your internally crafted image prompt>" \
--video-prompt "<your internally crafted motion prompt>" \
--audio-type <music|sfx|tts> \
--audio-prompt "<your internally crafted audio prompt>" \
--duration <seconds> \
--aspect-ratio <ratio> \
--style "<global style string you chose>"For text-to-video shots (no reference frame needed):
node {baseDir}/tools/director.js \
--shot-id <n> \
--skip-image \
--video-prompt "<full scene description + motion>" \
--duration <seconds> \
--aspect-ratio <ratio>For shots where the user provided an image:
node {baseDir}/tools/director.js \
--shot-id <n> \
--image-url "<url from user>" \
--video-prompt "<motion description>" \
--audio-type <type> \
--audio-prompt "<sound>" \
--duration <seconds>Step 4 — Present the results
After all shots are complete, show only the production output — no prompts, no model names:
## 🎬 [Title]
**[Shot count] shots · [format] · [total duration]**
---
**Shot 1 — [Scene Name]**
🖼 [image_url]
🎬 [video_url]
🔊 [audio description or "no audio"]
**Shot 2 — [Scene Name]**
...
---
Ready to adjust any shot or generate more?---
Shot Planning Reference (internal use only)
Shots by format
| Length | Shots |
|---|---|
| 15–20 s | 3–4 shots |
| 30 s | 5–6 shots |
| 45–60 s | 7–9 shots |
Shot sequence patterns
Brand / product (30 s): Establishing → Product detail close-up → Action/usage → Sensory moment → Lifestyle → Brand outro
Social reel (15 s): Hook (bold visual) → Core message → Payoff/result → CTA
Short film teaser (45 s): World → Character → Inciting moment → Action/tension → Emotional peak → Cliffhanger
Audio rule
- Assign music to the opening shot and closing shot
- Assign SFX to action shots (pouring, movement, impact)
- Use TTS only if user explicitly asks for narration or voiceover
- Omit audio for transitional shots when in doubt
Style consistency
Pick ONE style lock before executing and use it in --style for every shot. Example: cinematic, warm amber tones, shallow depth of field.
---
Example
User: "Make a short video about a rainy Tokyo street at night."
You internally plan:
- 4 shots · 16:9 · ~20 s
- Style:
cinematic, neon-wet streets, shallow depth of field, rain - Shot 1: wide establishing (music), Shot 2: close-up puddle reflection (SFX rain), Shot 3: person with umbrella tracking (SFX city ambience), Shot 4: neon sign fade-out (music outro)
Then execute all 4 shots silently and show only the results.
{
"name": "videoagent-director",
"version": "1.0.0",
"description": "AI creative director — turns a concept into a storyboard and generates images, video clips, and audio shot by shot.",
"type": "module",
"engines": {
"node": ">=18"
},
"dependencies": {}
}
🎬 VideoAgent Director
Turn any creative idea into a shot-by-shot production. The Director skill plans a storyboard from your concept and generates each shot's assets — reference image, video clip, and audio — automatically.
One prompt. A complete storyboard. All assets generated.
---
What It Does
1. Analyzes your brief — extracts format, tone, key shots 2. Plans the storyboard — breaks the concept into 4–8 shots with clear visual and audio direction 3. Executes shot by shot — for each shot:
- Generates a reference frame (image)
- Uses it to create a video clip (image-to-video for visual consistency)
- Adds audio — music, SFX, or voiceover
4. Delivers the production — a formatted storyboard with all asset URLs
---
Quick Start
Just describe what you want in plain language:
"Make a 30-second brand video for a minimalist coffee brand. Instagram vertical format."
"Create a short film teaser for a sci-fi story about a lone astronaut discovering a signal from Earth."
"Produce a product launch reel for a smartwatch. 15 seconds, energetic."
No prompts to write, no model to pick. The Director handles everything and delivers the final assets.
---
Models Used
| Asset | Service | Models Available |
|---|---|---|
| Reference image | VideoAgent Image Studio | Flux, Ideogram, Recraft, SDXL |
| Video clip | VideoAgent Video Studio | Kling, MiniMax, Veo, Seedance, Grok, Hunyuan |
| Audio | VideoAgent Audio Studio | ElevenLabs TTS/SFX, CassetteAI Music |
All services run through hosted proxies — no API keys needed.
---
Supported Formats
| Format | Aspect Ratio | Best For |
|---|---|---|
| Landscape | 16:9 | YouTube, presentations, cinema |
| Vertical | 9:16 | Instagram Reels, TikTok, Stories |
| Square | 1:1 | Instagram feed, thumbnails |
---
Shot Pipeline
For each shot in the storyboard:
User intent
↓
Storyboard plan (shot list with prompts)
↓ [for each shot]
Image generation (reference frame)
↓
Video generation (image-to-video)
↓
Audio generation (music / SFX / TTS)
↓
Shot result: { image_url, video_url, audio_url }---
Tool Usage
node tools/director.js \
--shot-id 1 \
--image-prompt "close-up of hands holding a warm coffee cup, morning light, editorial" \
--video-prompt "camera slowly pushes in, steam curls upward" \
--audio-type music \
--audio-prompt "gentle acoustic guitar, warm morning mood" \
--duration 5 \
--aspect-ratio 9:16 \
--style "warm amber tones, shallow depth of field, editorial photography"Full parameter reference: SKILL.md
---
Environment Variables
All optional — the skill works out of the box with hosted proxies.
| Variable | Default | Description |
|---|---|---|
IMAGE_PROXY_URL | https://image-gen-proxy.vercel.app | Image generation proxy |
VIDEO_PROXY_URL | https://pexo-video-deploy.vercel.app | Video generation proxy |
AUDIO_PROXY_URL | https://audiomind-proxy.vercel.app | Audio proxy |
IMAGE_STUDIO_TOKEN | (auto-fetched) | Pre-fetched image token |
VIDEO_STUDIO_TOKEN | (auto-fetched) | Pre-fetched video token |
AUDIOMIND_KEY | (none) | Pro key for audio proxy |
---
Knowledge Base
- references/storyboard_guide.md — Shot types, pacing, audio strategy, and prompt glossary
Storyboard Guide — Prompt Patterns and Pacing
A reference for writing effective storyboard scripts. Covers shot types, pacing rules, and prompt language for each asset type.
---
Shot Structure
Every shot in a storyboard has four elements:
| Element | What to Define |
|---|---|
| Visual frame | Composition, subject, lighting, style |
| Motion | Camera movement, subject movement, atmosphere |
| Duration | How long the shot runs (4–10 s is typical) |
| Audio | Music, SFX, narration, or silence |
---
Shot Types and When to Use Them
Establishing Shot
- Purpose: Open a scene, provide context and scale
- Camera: Wide, high angle, or drone
- Example:
Aerial shot of a coastal town at sunset, warm orange glow, cinematic wide angle - Duration: 5–8 s
Close-Up
- Purpose: Emotion, product detail, texture
- Camera: Tight framing, macro if needed
- Example:
Extreme close-up of coffee beans in a scoop, shallow depth of field, soft studio light - Duration: 3–5 s
Medium Shot
- Purpose: Action, character interaction, storytelling
- Camera: Waist-up framing
- Example:
Medium shot of a barista at work, steam rising from espresso machine in background - Duration: 4–6 s
Tracking Shot
- Purpose: Follow a subject, build momentum
- Camera: Smooth lateral or forward movement
- Example:
Camera tracks alongside a cyclist through a city street, motion blur on edges, golden hour - Duration: 5–8 s
POV Shot
- Purpose: Immersive, first-person experience
- Camera: Handheld or slightly shaky
- Example:
POV looking down at hands holding a warm mug, cozy morning light, soft focus background - Duration: 3–5 s
Cutaway
- Purpose: B-roll, context, transition
- Camera: Static or slow movement
- Example:
Slow zoom into a rain-streaked window, city lights blurred in background - Duration: 3–5 s
---
Pacing Patterns
Brand / Product Video (30 s)
Shot 1 (6 s) — Establishing: set the scene and mood
Shot 2 (5 s) — Close-up: product or key detail
Shot 3 (5 s) — Action: someone using the product
Shot 4 (5 s) — Close-up: sensory moment (steam, texture, taste)
Shot 5 (4 s) — Medium: person enjoying / benefitting
Shot 6 (5 s) — Logo / brand revealSocial Reel (15 s, vertical 9:16)
Shot 1 (3 s) — Hook: bold visual that grabs attention in 1 s
Shot 2 (4 s) — Core message: product / action
Shot 3 (4 s) — Payoff: reaction or result
Shot 4 (4 s) — CTA or outroShort Film Teaser (45 s)
Shot 1 (8 s) — Establishing: world and atmosphere
Shot 2 (6 s) — Character introduction
Shot 3 (5 s) — Inciting moment / conflict hint
Shot 4 (6 s) — Action or tension
Shot 5 (8 s) — Emotional peak
Shot 6 (6 s) — Unresolved cliffhanger
Shot 7 (6 s) — Title card or tagline---
Audio Strategy
Music
Best for: sustained mood, emotional continuity across multiple shots.
| Mood | Prompt Example |
|---|---|
| Calm / morning | gentle piano, warm acoustic guitar, lo-fi morning |
| Energetic | upbeat electronic, driving beat, 120 BPM |
| Cinematic / epic | orchestral swell, strings, rising tension |
| Sad / reflective | sparse piano, minor key, ambient fade |
| Corporate | clean corporate pop, positive, modern |
Use music for: opening shot, ending shot, transitional shots without strong action.
Sound Effects (SFX)
Best for: specific events within a shot.
| Situation | Prompt Example |
|---|---|
| Coffee / liquid | espresso pouring, liquid stream, gentle splash |
| Nature | ocean waves, seagulls, light wind |
| City | traffic hum, distant chatter, rain on pavement |
| Tech / UI | keyboard typing, soft notification chime |
| Food | sizzling pan, knife on cutting board, ice in glass |
Use SFX for: action shots, product shots, sensory moments.
Narration / TTS
Best for: story-driven content, explainer videos, documentary style.
Rules:
- Keep each line under 20 words
- Match the line to the shot duration (5 s shot ≈ 10–15 words at normal pace)
- Write conversational, not formal
| Shot Duration | Max Words |
|---|---|
| 3–4 s | 8–10 words |
| 5–6 s | 12–15 words |
| 7–8 s | 18–22 words |
---
Prompt Language Glossary
Image prompts — composition terms
close-up,extreme close-up,medium shot,wide shot,aerial,overheadrule of thirds,centered composition,foreground / backgroundshallow depth of field,bokeh background,sharp throughout
Image prompts — lighting
soft morning light,golden hour,blue hour,overcast diffusedstudio lighting,backlit silhouette,rim light,neon-litcandlelight,harsh midday sun,fog-filtered light
Image prompts — style modifiers
cinematic,editorial photography,film still,35mm grainproduct shot,commercial photography,lifestyle photographyillustration,concept art,3D render,watercolor
Video prompts — camera movement
static shot(no movement)camera slowly pushes in / pulls backslow pan left / rightsmooth upward tilttracking alongside the subjectdrone ascending slowlyhandheld, slight sway
Video prompts — subject motion
steam rises gently,fabric sways in breeze,water ripplesperson walks toward camera,hand reaches into frameeyes close slowly,slight smile formsliquid pours in slow motion
---
Style Consistency
To keep all shots visually cohesive, choose a style lock before generating and append it to every prompt.
Example style locks
| Project Type | Style Lock |
|---|---|
| Minimalist brand | clean white space, soft studio light, editorial, product photography |
| Cinematic short film | cinematic, anamorphic lens, warm amber tones, shallow DOF, 35mm film |
| Social lifestyle | bright and airy, natural daylight, lifestyle photography, Canon 5D |
| Corporate / tech | clean modern office, cool blue tones, sharp focus, professional |
| Dark / moody | low key lighting, deep shadows, noir, desaturated except highlights |
---
Common Mistakes to Avoid
| Mistake | Fix |
|---|---|
| Describing appearance in video prompt | Video prompt = motion only; appearance is in image prompt |
| Too many concepts in one shot | One idea per shot; split complex scenes |
| Audio not matching shot duration | A 5 s shot needs 5 s of audio; avoid long intros |
| Inconsistent style across shots | Always use a style lock string |
| Vague motion ("it moves") | Be specific: "camera slowly pushes in 20%", "subject turns left" |
#!/usr/bin/env node
/**
* director.js — VideoAgent Director shot executor.
*
* Generates one storyboard shot: image frame → video clip → audio.
* Runs as a Node.js ESM script (Node 18+).
*
* Usage:
* node director.js [options]
*
* Quick examples:
* # Full shot (image → video → music)
* node director.js \
* --image-prompt "close-up of a coffee cup, steam rising, warm light" \
* --video-prompt "camera slowly pushes in, steam drifts upward" \
* --audio-type music \
* --audio-prompt "gentle acoustic guitar, calm morning mood" \
* --duration 5 --aspect-ratio 16:9
*
* # Animate an existing image
* node director.js \
* --image-url "https://example.com/frame.jpg" \
* --video-prompt "gentle wind in the hair, soft bokeh background" \
* --duration 5
*
* # Text-to-video only (no image generation)
* node director.js \
* --skip-image \
* --video-prompt "aerial drone shot over a misty forest at dawn, cinematic" \
* --duration 6
*/
import { parseArgs } from "node:util";
import os from "node:os";
import path from "node:path";
import fs from "node:fs";
// ── Proxy endpoints ──────────────────────────────────────────────────────────
const IMAGE_PROXY = process.env.IMAGE_PROXY_URL || "https://image-gen-proxy.vercel.app";
const VIDEO_PROXY = process.env.VIDEO_PROXY_URL || "https://pexo-video-deploy.vercel.app";
const AUDIO_PROXY = process.env.AUDIO_PROXY_URL || "https://audiomind-proxy.vercel.app";
// ── Token cache (per session) ─────────────────────────────────────────────────
const TOKEN_CACHE_FILE = path.join(os.tmpdir(), "director-tokens.json");
function loadTokenCache() {
try {
const raw = fs.readFileSync(TOKEN_CACHE_FILE, "utf8");
return JSON.parse(raw);
} catch {
return {};
}
}
function saveTokenCache(cache) {
try { fs.writeFileSync(TOKEN_CACHE_FILE, JSON.stringify(cache), "utf8"); } catch {}
}
// ── HTTP helpers ──────────────────────────────────────────────────────────────
async function post(url, body, headers = {}) {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json", ...headers },
body: JSON.stringify(body),
});
const text = await res.text();
try { return { status: res.status, data: JSON.parse(text) }; }
catch { return { status: res.status, data: { error: text } }; }
}
async function get(url, headers = {}) {
const res = await fetch(url, { headers });
const text = await res.text();
try { return { status: res.status, data: JSON.parse(text) }; }
catch { return { status: res.status, data: { error: text } }; }
}
function fail(msg) {
console.error(JSON.stringify({ success: false, error: msg }));
process.exit(1);
}
// ── Image token ───────────────────────────────────────────────────────────────
async function getImageToken() {
const envToken = process.env.IMAGE_STUDIO_TOKEN;
if (envToken) return envToken;
const cache = loadTokenCache();
if (cache.imageToken) return cache.imageToken;
const r = await post(`${IMAGE_PROXY}/api/token`, {});
if (r.status !== 200 || !r.data.token) fail(`Image token error: ${JSON.stringify(r.data)}`);
cache.imageToken = r.data.token;
saveTokenCache(cache);
return r.data.token;
}
// ── Video token ───────────────────────────────────────────────────────────────
async function getVideoToken() {
const envToken = process.env.VIDEO_STUDIO_TOKEN;
if (envToken) return envToken;
const cache = loadTokenCache();
if (cache.videoToken) return cache.videoToken;
const r = await post(`${VIDEO_PROXY}/api/token`, {});
if (r.status !== 200 || !r.data.token) fail(`Video token error: ${JSON.stringify(r.data)}`);
cache.videoToken = r.data.token;
saveTokenCache(cache);
return r.data.token;
}
// ── Image generation ──────────────────────────────────────────────────────────
async function generateImage({ prompt, model = "flux-schnell", aspectRatio = "16:9" }) {
const token = await getImageToken();
const r = await post(
`${IMAGE_PROXY}/api/generate`,
{ model, prompt, aspect_ratio: aspectRatio },
{ "X-ImageGen-Token": token }
);
if (r.status !== 200 || !r.data.image_url) {
fail(`Image generation failed (${r.status}): ${JSON.stringify(r.data)}`);
}
return r.data.image_url;
}
// ── Video generation ──────────────────────────────────────────────────────────
async function generateVideo({ prompt, imageUrl, model, duration, aspectRatio }) {
const token = await getVideoToken();
const mode = imageUrl ? "image-to-video" : "text-to-video";
const body = {
mode,
prompt,
duration: Number(duration) || 5,
aspect_ratio: aspectRatio || "16:9",
...(model && { model }),
...(imageUrl && { image_url: imageUrl }),
};
const r = await post(`${VIDEO_PROXY}/api/generate`, body, {
Authorization: `Bearer ${token}`,
});
if (r.status !== 200 || !r.data.videoUrl) {
fail(`Video generation failed (${r.status}): ${JSON.stringify(r.data)}`);
}
return r.data.videoUrl;
}
// ── Audio generation ──────────────────────────────────────────────────────────
async function generateAudio({ type, prompt, voiceId }) {
const audioKey = process.env.AUDIOMIND_KEY || "";
const headers = audioKey ? { "X-Audiomind-Key": audioKey } : {};
const body = { action: type };
if (type === "tts") {
body.text = prompt;
if (voiceId) body.voice_id = voiceId;
} else {
body.prompt = prompt;
}
const r = await post(`${AUDIO_PROXY}/api/audio`, body, headers);
if (r.status !== 200) {
// Audio failure is non-fatal — warn and continue
return { error: `Audio failed (${r.status}): ${JSON.stringify(r.data)}` };
}
return {
audio_url: r.data.audio_url || null,
audio_base64: r.data.audio_base64 || null,
format: r.data.format || "mp3",
};
}
// ── Prompt helpers ────────────────────────────────────────────────────────────
function appendStyle(prompt, style) {
if (!style || !prompt) return prompt || "";
return `${prompt}, ${style}`;
}
// ── Parse CLI args ────────────────────────────────────────────────────────────
const { values: args } = parseArgs({
options: {
"shot-id": { type: "string", default: "1" },
"image-prompt": { type: "string" },
"image-url": { type: "string" },
"skip-image": { type: "boolean", default: false },
"video-prompt": { type: "string" },
"video-model": { type: "string" },
"image-model": { type: "string", default: "flux-schnell" },
"audio-type": { type: "string" },
"audio-prompt": { type: "string" },
"audio-voice": { type: "string" },
"skip-audio": { type: "boolean", default: false },
"duration": { type: "string", default: "5" },
"aspect-ratio": { type: "string", default: "16:9" },
"style": { type: "string" },
},
strict: false,
});
// ── Main ──────────────────────────────────────────────────────────────────────
async function main() {
const shotId = args["shot-id"];
const style = args["style"] || "";
const aspectRatio = args["aspect-ratio"] || "16:9";
const duration = args["duration"] || "5";
if (!args["video-prompt"]) fail("--video-prompt is required");
const result = {
shot_id: shotId,
success: false,
image_url: null,
video_url: null,
audio_url: null,
image_prompt: null,
video_prompt: null,
audio_prompt: null,
};
// ── 1. Image ────────────────────────────────────────────────────────────────
let imageUrl = args["image-url"] || null;
if (!args["skip-image"] && !imageUrl) {
if (!args["image-prompt"]) {
// Auto-derive a basic image prompt from the video prompt
args["image-prompt"] = args["video-prompt"];
}
const imagePrompt = appendStyle(args["image-prompt"], style);
result.image_prompt = imagePrompt;
process.stderr.write(`[Shot ${shotId}] Generating reference image...\n`);
imageUrl = await generateImage({
prompt: imagePrompt,
model: args["image-model"] || "flux-schnell",
aspectRatio,
});
result.image_url = imageUrl;
process.stderr.write(`[Shot ${shotId}] Image ready: ${imageUrl}\n`);
} else if (imageUrl) {
result.image_url = imageUrl;
}
// ── 2. Video ────────────────────────────────────────────────────────────────
const videoPrompt = appendStyle(args["video-prompt"], style);
result.video_prompt = videoPrompt;
process.stderr.write(`[Shot ${shotId}] Generating video clip...\n`);
const videoUrl = await generateVideo({
prompt: videoPrompt,
imageUrl,
model: args["video-model"] || undefined,
duration,
aspectRatio,
});
result.video_url = videoUrl;
process.stderr.write(`[Shot ${shotId}] Video ready: ${videoUrl}\n`);
// ── 3. Audio ────────────────────────────────────────────────────────────────
if (!args["skip-audio"] && args["audio-type"] && args["audio-prompt"]) {
const audioPrompt = args["audio-prompt"];
result.audio_prompt = audioPrompt;
process.stderr.write(`[Shot ${shotId}] Generating audio (${args["audio-type"]})...\n`);
const audio = await generateAudio({
type: args["audio-type"],
prompt: audioPrompt,
voiceId: args["audio-voice"],
});
if (audio.error) {
process.stderr.write(`[Shot ${shotId}] Audio warning: ${audio.error}\n`);
} else {
result.audio_url = audio.audio_url;
result.audio_base64 = audio.audio_base64;
result.audio_format = audio.format;
process.stderr.write(`[Shot ${shotId}] Audio ready.\n`);
}
}
result.success = true;
console.log(JSON.stringify(result, null, 2));
}
main().catch(err => fail(err.message));
Related skills
How it compares
Pick videoagent-director for end-to-end multi-shot agent video pipelines; pick single-model image skills when only one still frame is needed.
FAQ
What does videoagent-director produce?
videoagent-director plans shots from a natural-language brief, runs director.js for each scene, and returns image URLs, video clip URLs, and audio assets in a production report without exposing internal prompts.
How many shots does videoagent-director plan?
videoagent-director targets 3–4 shots for 15–20 second videos, 5–6 for 30 seconds, and 7–9 for 45–60 seconds, with brand, social reel, and short-film sequence patterns.