StyleCast turns a folder of property photos into a cinematic, professionally-edited tour — then reproduces the exact edit on any other shoot. Author a style once, apply it to every listing.
“Play the original edit and a generated edit side by side — nearly identical, just a different house.” Frame-locked, exactly as briefed.
Each style is a portable template — authored once or extracted from a reference reel, then reused on every listing. Browse with bun run styles.
Cinematic editorial — establishing push-in, smooth glides, a detail beat, rising close.
Warm, dreamy sunset tour — slow drifting moves and amber light. Room-aware + beat-synced.
Bright, airy, crisp — clean glides and high-key daylight.
Punchy social cut — fast 4-second beats for Instagram / TikTok.
Each photo runs the same four stages, in parallel across shots.
Every source photo is cropped to the template’s aspect ratio so the video model never letterboxes.
Nano Banana 2 restyles the still to editorial lighting and depth — composition preserved.
Veo 3.1 Fast turns the still into a 6-second clip with the shot’s movement.
ffmpeg concats the clips in order and lays the soundtrack. Out comes the tour.
Image edit and image→video both run through OpenRouter. No multi-vendor glue.
Every model is a string in the template — Veo today; Kling 3.0, Seedance 2.0 one edit away.
Shots render in parallel and cache to disk, so iterating on a cut costs nothing.
Bun, ffmpeg, and a single OpenRouter key. Copy, paste, render.
# prerequisites: bun + ffmpeg brew install ffmpeg bun install # one key powers image + video printf 'OPENROUTER_API_KEY=sk-or-...' > .env
# cheap end-to-end check (~$0.5) bun src/scripts/smoke.ts # apply a style to a photoshoot bun src/cli.ts --style luxury-tour \ --photos shoots/extracted/<shoot>
bun src/cli.ts --style luxury-tour --photos "shoots/extracted/213_Hidden_Dune_Ct_Ponte_Vedra_Beach_FL_32082_USA_" bun src/cli.ts --style luxury-tour --photos "shoots/extracted/622_Camino_Santa_Barbara" bun src/scripts/sidebyside.ts out/luxury-tour__213_*.mp4 out/luxury-tour__622_*.mp4 out/sidebyside.mp4
Flags · --force re-renders cached clips · bun run models lists every video model · bun run site serves this page
Not a render — a portable JSON template. “Apply style X to shoot Y” = run shoot Y’s photos through template X. That single idea is why the two-house demo works.
{
"id": "luxury-tour",
"aspectRatio": "16:9", "resolution": "720p",
"enhanceModel": "google/gemini-3.1-flash-image-preview",
"motionSuffix": "single continuous take, no cuts, stable motion",
"shots": [
{
"photoIndex": 0,
"enhancePrompt": "cinematic editorial, directional light…",
"movementPrompt": "super smooth camera moves forward, cinematic",
"durationSec": 6, "videoModel": "google/veo-3.1-fast"
}
// … 5 more beats: glide · orbit · detail · truck · crane-up
]
}
A vision model classifies each photo and maps shot roles to matching rooms.
Detect the track’s BPM and snap every cut to the beat.
Upload a reference video; auto-extract its shot list, movements and pacing into a template.
Swap a room or reshuffle shots in the browser, then re-export — on top of the cached clips.