Skip to content

Commit 3dc5f91

Browse files
committed
fix: the promo recorder runs from a fresh install
From the review on #9. - playwright was imported but not declared, so `bun promo/record.mjs` failed after a fresh install. It is a dev dependency now; the browser is still a separate one-off download, noted at the top of the script. - The page's file URL is built with pathToFileURL, so a folder named with #, ? or % stays a path. - The PROMO_DIR override is gone: it existed only to run the script from outside the repo while playwright was missing.
1 parent ebcfde8 commit 3dc5f91

3 files changed

Lines changed: 17 additions & 7 deletions

File tree

‎bun.lock‎

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@types/node": "^22.0.0",
3232
"esbuild": "^0.25.0",
3333
"jsdom": "^26.0.0",
34+
"playwright": "^1.63.0",
3435
"prettier": "^3.6.0",
3536
"typescript": "^5.9.0",
3637
"vitest": "^3.2.0"

‎promo/record.mjs‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
// Renders promo/sliders.html to an MP4, one frame at a time, so the result is
2-
// smooth whatever the machine: `bun promo/record.mjs [name]` renders promo/<name>.html
3-
// to promo/sharp-<name>.mp4 (needs playwright and ffmpeg). Default name: simple.
4-
// A square cut: `bun promo/record.mjs list-square 1080 1080 1`.
1+
// Renders a promo page to an MP4, one frame at a time, so the result is smooth
2+
// whatever the machine: `bun promo/record.mjs [name]` renders promo/<name>.html to
3+
// promo/sharp-<name>.mp4. Default name: simple. A square cut:
4+
// `bun promo/record.mjs list-square 1080 1080 1`.
5+
// Needs ffmpeg, and a browser for playwright: `bunx playwright install chromium`.
56
import { chromium } from 'playwright';
67
import { mkdir, rm } from 'node:fs/promises';
78
import { execFileSync } from 'node:child_process';
8-
import { fileURLToPath } from 'node:url';
9+
import { fileURLToPath, pathToFileURL } from 'node:url';
910
import path from 'node:path';
1011

11-
const here = process.env.PROMO_DIR ?? path.dirname(fileURLToPath(import.meta.url));
12+
const here = path.dirname(fileURLToPath(import.meta.url));
1213
const frames = path.join(here, '.frames');
1314
const FPS = 30;
1415
const name = process.argv[2] ?? 'simple';
@@ -22,7 +23,10 @@ await mkdir(frames, { recursive: true });
2223

2324
const browser = await chromium.launch();
2425
const page = await browser.newPage({ viewport: { width, height }, deviceScaleFactor: scale });
25-
await page.goto(`file://${path.join(here, `${name}.html`)}?still`);
26+
// Built as a URL, not a string: a folder named with #, ? or % stays a path.
27+
const url = pathToFileURL(path.join(here, `${name}.html`));
28+
url.searchParams.set('still', '');
29+
await page.goto(url.href);
2630
await page.evaluate(() => document.fonts.ready);
2731
const duration = await page.evaluate(() => window.DURATION);
2832
const total = Math.round(duration * FPS);

0 commit comments

Comments
 (0)