I stopped recording my screen to make demo videos
The demo is a webpage. Claude Code drives the browser. ffmpeg does the rest.
Every time I shipped a side project, the same wall showed up at the end: the demo video. The thing people actually watch before they read a word. And the normal way to make one is miserable.
You open a screen recorder, rehearse the clicks, fluff a take, redo it. You drop the clip into an editor, trim, add a caption, render. The export looks soft because a video codec compressed your crisp UI into smears. You spot a typo in the third second, and now you re-record the whole thing. A two minute clip eats an afternoon.
So I stopped recording my screen. Here is what I do instead.
The demo is a webpage
The trick is to stop treating the screen as the source of truth. The screen is a lossy copy of something. Make that something a file you control.
I write the demo as a single HTML page. CSS animations for the motion, a tiny JavaScript timeline for the choreography. A dashboard fades in, a chart draws itself, a row slams into place, a number counts up. None of it is a recording of a real app. It is a reconstruction of the app’s interface in its own colors and fonts, built to play on a clock.
Two things make this page recordable rather than just pretty.
First, one knob controls all the timing. Every duration in the CSS reads calc(var(--d) * 0.6s) instead of a hard 0.6s. Set --d to 1 and it plays at normal speed in the browser. Set it to 7 and the whole demo crawls, uniformly, every transition stretched by the same factor. That single variable is what lets me slow the motion down later without re-timing anything by hand.
Second, the page reports where it is. A small script schedules each beat with at(ms, fn), exposes the current animation time on window.__t, and flips window.__demoDone to true at the end. So a script driving this page always knows the exact frame it is looking at and when the show is over.
Claude Code drives the browser
This is where the Playwright MCP comes in. I ask Claude Code to open the page in Chrome, crank --d up so everything plays in slow motion, and then sit in a loop: grab a frame, check the animation clock, grab the next frame, until the page says it is done.
The frames come out through Chrome’s DevTools protocol as plain JPEGs, not through a video encoder. That is the whole point. There is no codec in the capture loop, so there is no compression smear. Each frame is stamped with the window.__t value it was taken at, so I know its real position on the timeline rather than guessing from a frame count.
The slow motion is not for looks. The capture runs at about eleven frames a second, which would be a stutter at real speed. But the page is playing at fifteen percent of normal, so those eleven real captures cover a sliver of actual motion. Stretch them back out and you get more than seventy distinct frames for every second of final video. You are sampling the animation far denser than the output needs.
ffmpeg puts it back together
Now I have a folder of JPEGs and a timestamp for each one. I hand ffmpeg the list with each frame’s real duration and ask for a constant sixty frames a second, H.264, high quality.
Because the captured frame rate is higher than sixty, ffmpeg picks real frames to land on each output slot instead of duplicating one or inventing a blurry in-between. The result is genuine sixty frames a second of motion, built entirely from frames that actually existed, so the interface stays sharp and nothing smears.
If I want sound, ffmpeg muxes a CC0 track underneath, trimmed to length with gentle fades and normalized so the music sits under the visuals instead of fighting them. A few seconds of the best beat get pulled out as a looping GIF for social.
What this buys you
Here are three reels made this exact way. Each one reconstructs a product’s real interface and plays it on a timeline, captured frame by frame, never recorded.
The reason I will never go back: it is code, so it is repeatable. A stat is wrong? Change a number and rerun. A beat feels rushed? Nudge one timestamp. Want the same demo for four different products? Loop over four pages and render them all while you make coffee. There is no take to redo and no quality lost to another export.
The studio is a browser. The editor is a script. The footage never touches a codec until the last step, so it stays sharp the whole way through.
Next
I am writing one of these a week: how I actually work with AI as a senior engineer, and the small mechanical tricks that turn out to matter. If that sounds useful, subscribe and the next one lands in your inbox.
One question back to you, because it shapes what I write next: what is the last thing you made that took an afternoon and should have taken ten minutes? Reply and tell me. I read every one.


