--- name: video description: Make trailers, music videos, cutscenes and page recordings for a Homie studio — a gameplay trailer captured from the studio's own running game and cut on the beat of its music; a recording of any web page while a script drives it (clicks, taps, keys, typing, scrolls, waits; Play and a few moves on the studio's own game page; a site walkthrough or product demo) in real time with honest frames; or generated footage from fal (Seedance and friends) through the creator's OWN fal account under a hard budget with a receipt for every call, drawn over with a JavaScript look and kinetic type, sync-checked, reviewed on contact sheets, delivered 16:9 and 9:16, and published as a video page on the studio's site (big files in the studio's own R2 when it has storage). Use when someone in a studio asks for a trailer, a teaser, a music video, a cutscene, a clip for social media, "a video of my game", a demo, a walkthrough or tutorial video of a site or app, or a recording of a page. compatibility: Node 22, ffmpeg and Chrome. Generated footage uses the creator's own fal account (FAL_KEY); fal's own MCP server (https://mcp.fal.ai/mcp-relay) finds models and reads prices. metadata: providers: fal --- # Video for a studio A studio is the folder with `studio.json`. Videos live in `videos//`, listed in `videos/manifest.json`; a published entry is a page at `/videos//` on the studio's site, playing the 16:9 cut (the 9:16 cut on a portrait phone). Everything runs through `scripts/video.mjs` in this skill's folder (Claude Code: `node "${CLAUDE_PLUGIN_ROOT}/skills/video/scripts/video.mjs" `), from inside the studio. It needs Node 22, ffmpeg and Chrome; `--json` on every command. Check disk before any capture or render (`df -h .`): keep 10 GB free. Raw frames are deleted once encoded. Finish in this turn: start the local site with the app's background-task tool (not `nohup ... &` inside a command, which dies with the command) and wait on it. ## The rules that come first `references/HONESTY.md` has them in full. In short: - **No fabricated gameplay.** Anything shown as the game is captured from the game running. A generated shot is never passed off as gameplay, and a trailer that mixes both says which is which. Bots are bots: never imply a crowd that was not there. - **No real people, no real brands.** No likeness, voice or name of a real person, no real logo, product or copyrighted character, in prompts, references or type. - **Money only with a budget.** Every paid call is priced first, fits inside the cap the person set, and leaves a receipt the moment the provider accepts it. ## Which video - **A gameplay trailer** (15 to 60 s): real footage of the studio's own game, cut on the beat of the studio's music. No provider, no money. Recipe: section A below, detail in `references/TRAILER.md`. - **A music video, a cutscene, a teaser with generated footage**: fal models under a budget, then drawn over. Section B, detail in `references/METHOD.md`. - **A recording of a page while it is used**: the studio's own game page (land, press Play, play a little), a site walkthrough, a product demo, a tutorial. A steps file drives it. Section C, detail in `references/RECORD.md`. Both start with `node check` (ffmpeg, Chrome, the studio; fal only if a key is set). ## A. A gameplay trailer **One command** films the game, rebuilds its sound, picks the shots and delivers three shapes: ```sh npm run dev # background task; the site at http://127.0.0.1:8787 node trailer --game --url http://127.0.0.1:8787 --seconds 45 --length 20 --title "" --end "Play free" ``` (`npx --no-install homie-studio trailer …` is the same command, into `videos/-trailer/`.) - It renders the game **frame by frame on a virtual clock**: in each frame the page's `requestAnimationFrame`, `performance.now`, `Date`, `setTimeout`, `setInterval` and its CSS and Web animations all move on by exactly 1/30 s, then the frame is copied. No frame is ever held, however heavy the game or slow the computer (`heldFrames` is 0; `speed` says how it compared with real time). - **The sound is rebuilt, not recorded.** The `sound` skill's player (`sound.js`) logs every sound it schedules when a recorder asks; the files it names are fetched from the game's own address and mixed again on the film's clock (`work/capture/sound.wav`, and `sfx.wav` and `music.wav` apart). A game whose sound does not go through `sound.js` (and does not push the same events) comes out silent, and the result says so: use `capture` below for those, which records the speaker in real time. - **The shots are picked from what the game played**: a rare sound (a win, an explosion) counts for more than a common one (a step), with the picture's motion as the smaller part. When the game played music, a shot is a bar of it and the music runs on under the cuts; `shotsPlayed` says what is in each shot. `work/edl.json` is the edit: change it and run `cut --square`. - Out: `.mp4` (16:9), `-square.mp4` (1:1), `-vertical.mp4` (9:16), a poster, an end card (and a title card with `--title`) in the game's look. `--keep-capture` edits the film already made (another `--length`, another `--end`) without filming again. `--steps ` presses things while it films (`references/RECORD.md`; only wait, waitFor, click, tap, key, keys, type, focus). - **What the virtual clock does not reach**: the audio clock, `