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 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.