command-line tool · URL in, walkthrough mp4 out

Reel

Point it at a URL, get a clean scroll-walkthrough mp4. One command.

status live · CLIrole designed + built end to end
recorded runlive
Reel recording phoebemusic.com from one command: the entrance, the day-to-night scroll, and back to top. 26 seconds, unedited.
1 commandurl in, an embeddable mp4 out, no editing step.
1 filethe whole tool is one script, no framework.
6 sitesevery site walkthrough on this portfolio, recorded with this tool or the script it grew from.
2 depsPlaywright and ffmpeg do the work, nothing else at runtime.
What it solves

Every site in this portfolio needed a walkthrough clip, and each time I was hand-writing the same Playwright-plus-ffmpeg script, tweaking scroll timing and transcode flags by hand. That is a tool pretending to be a one-off. Reel is the script promoted to a real command with sane defaults, so recording a site is one line instead of a copy-paste I re-debug every time.

The constraint

It had to stay honest about what a headless browser can actually do. No fake screen recorder that claims to capture anything: it records what an anonymous visitor sees, which means login-gated and paywalled pages are out of scope, and it says so rather than producing a broken clip. One file, no dependencies beyond the two that do the real work.

Who it serves

Anyone shipping marketing sites who needs walkthrough clips for a deck, a case study, or a handoff.

Who it is for

A small tool built the way a workflow engineer builds: notice the repeated manual loop, name it, and replace it with one command.

How it works
  1. Give it a URLA bare hostname or a full URL both work, https is assumed.
  2. It records a real visitHeadless Chromium loads the page, waits out the entrance animation, then smooth-scrolls the whole page and back while capturing video.
  3. ffmpeg finishes itThe raw capture is transcoded to a faststart H.264 mp4, sized and quality-set by flags with sensible defaults.
  4. It lands ready to embedOutput drops into the current folder named after the site, ready for a case study or a slide.
The decision that was not obvious

Split the pure logic from the IO so the tool is testable. URL normalization and output-name derivation are exported functions with their own assert-based check, while the record-and-transcode step stays a thin shell around Playwright and ffmpeg. It would have been faster to write one procedural script, but the seam means the fiddly parsing is verified in a second and the tool is safe to change later. The same lesson that runs through the rest of this portfolio: put the part that can silently break behind a check.

What I would change if I rebuilt it today

Scroll timing is one global pace for the whole page. A dense hero and an empty footer get the same dwell, so busy sections feel rushed and sparse ones drag. I would measure section height or content density on the way down and vary the dwell per region, the same idea I flagged for the pixel-gallery transitions.

Built with
Node Playwright ffmpeg node:util parseArgs zero runtime deps beyond those