Video studio appPro
A complete video generation studio on scripted fixtures: the prompt bar with start frame, length, aspect and camera, takes that arrive frame by frame on honest progress, a player and a side by side compare, a storyboard, a multitrack edit, a render queue, credits and an export that records the edit to a file.
On this page
Installation
The template installs as a folder under components/chatcn/pro/video-studio-app/: the app, the rail, the generate, storyboard and edit views, the viewer, the export and the scripted engine, each a file you own and edit.
Usage
import { VideoStudioApp } from "@/components/chatcn/pro/video-studio-app/video-studio-app"
<VideoStudioApp
projects={projects}
takes={history}
models={models}
pool={stills}
credits={account.credits}
/>Give it a height: it fills its parent. Everything runs on the scripted engine in use-video-engine.ts, a render queue that turns a prompt into a take with a wait in line and frames that land at the model's pace. Takes play as stills performing their camera move, so nothing loads a video file. To go live, replace enqueue with your API, feed its progress events into the same take shape, and return videoClip(url) from takeSource; the filmstrip, the queue, the player and the edit follow on their own.
Examples
Storyboard mid render
Every shot joins the same queue as a take. Shot 4 failed earlier and renders again on its retry, shot 5 waits behind it, and the queue sits beside the board. Editing a finished shot marks it changed, so Generate changed only pays for what moved.
Edit and export
The export records the edit in the tab with recordCanvas, in real time, so its progress and time left are measured, not guessed. Pass onExport to render on your server instead. With 6 credits left, the prompt bar holds new runs and offers credits.
On a phone
Below 768 px the rail moves into a drawer, the views sit under the title, the queue opens as a sheet and every control keeps a 44 px target. Pass layout="mobile" to force it inside a device frame.
What is inside
- The shell is the free
ChatLayout: the rail collapses to icons withCmd+Band becomes a drawer under 768 px; the render queue is its side panel. VideoPromptBarwith start and end frames, length, aspect and camera motion, the model menu above it and the cost on Generate. A run that costs more than the balance is held, with Buy credits beside it.- The latest run on
RenderFilmstrip: frames land left to right through the dither reveal as the engine reports them, with Stop, Retry and time left. - Takes grouped by prompt. A take plays where it sits while the pointer rests on it; rendering takes show
DenoisePlaceholderon their real progress, failed ones say why and refund. - The viewer on
VideoPlayerPro(frame steps, J K L, in and out points) with what made the take and what to do next: add to the timeline, another take, use as start frame, pick as best. Compare plays up to four takes in lockstep onVideoCompare. ShotStoryboardwith Generate all and per shot retry, and Place on timeline to lay the finished shots end to end.- The edit on
ClipTimelinewith overlay, shots and score tracks, and a preview that draws the frame under the playhead. GenerationQueuewith reorder, cancel, retry and notify,ProgressToastStackwhile the queue is closed,CreditBalanceandCreditTopUp, and every shortcut inKeyboardShortcuts.
Props
| Prop | Type | Notes |
|---|---|---|
projects | { id, name, shots?, clips? }[] | The first one opens, with its storyboard and edit |
takes | VideoTake[] | Every take so far, newest first, each with its project |
models | VideoModel[] | Name, lengths and credits a second, for the model menu |
pool | VideoStill[] | Stills the scripted engine animates into takes |
shotStills | Record<string, VideoStill> | The still each storyboard shot renders from |
credits, spend | number, CreditSpend[] | Balance and recent spend at the start |
packs | CreditPack[] | For the top up dialog |
account | { name, plan } | The account menu at the foot of the rail |
defaultPrompt, defaultParams | string, Partial<VideoPromptParams> | The prompt bar at the start |
defaultView | "generate" | "storyboard" | "edit" | Default generate. Also defaultQueueOpen, defaultExportOpen |
onExport | (request) => Promise<Blob> | Render on your server. Default: recorded in the tab as WebM |
fail | (take) => string | undefined | Scripted engine only: make a take fail |
layout | "auto" | "desktop" | "mobile" | Force the phone layout inside a device frame |
now | number | Reference time for "4 min ago" |
Keyboard
| Key | Action |
|---|---|
/ | Write a prompt |
1, 2, 3 | Generate, storyboard or edit |
Q | Show or hide the render queue |
Cmd+Shift+E or Ctrl+Shift+E | Export the edit |
Cmd+B or Ctrl+B | Collapse or expand the rail |
Cmd+/ or Ctrl+/ | Every shortcut, grouped by area |
Enter, Shift+Enter | Generate, new line in the prompt |
Alt and arrows | Move a storyboard shot or a waiting job |
Space, J, K, L, ,, . | Play, shuttle and step frames in the player and timeline |
Accessibility
- Landmarks from the layout, a skip link to the studio, a named navigation for projects with
aria-currenton the open one, and the views as tabs. - The latest run is
aria-busywhile it renders and says once, politely, when the take is ready or failed. Frame by frame progress is never announced. - Each take is one button whose name starts with its visible label, then its length. Every composed part keeps its own semantics: the queue and storyboard reorder from the keyboard, the player is a labeled group with a frame slider, dialogs are modal.
- Refunds, exports, placements and shots sent to the queue are announced politely.
Motion
- Each composed component keeps its own motion: frames resolve through the dither reveal on real progress, shots and jobs glide when reordered, the queue slides in on the panel curve, toasts stack and fan, credits roll their digits.
- A take plays from its first frame while the pointer rests on it and stops when it leaves. Switching projects and views is instant.
- Under reduced motion take tiles stay on their poster, reveals fade and glides land at once.