// Renders a video into out/, in each shape asked for (wide, square, tall): // // node render.mjs change out/stories/.json [--formats wide,tall] // node render.mjs feature [--formats square] // // A change is told from a story change/story.mjs wrote; a feature reel // (video/Feature.tsx's REELS) plays takes shoot/shoot.mjs filmed. import { spawnSync } from 'node:child_process'; import { mkdirSync, writeFileSync } from 'node:fs'; import { basename, dirname, join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = dirname(fileURLToPath(import.meta.url)); const args = process.argv.slice(2); const at = args.indexOf('--formats'); const formats = at < 0 ? ['wide', 'square', 'tall'] : args.splice(at, 2)[1].split(','); const [kind, what] = args; if (!['change', 'feature'].includes(kind) || !what) { console.error( 'usage: render.mjs change | feature [--formats wide,square,tall]' ); process.exit(2); } mkdirSync(join(root, 'out'), { recursive: true }); let props; let name; if (kind === 'change') { props = resolve(what); name = `change-${basename(what, '.json')}`; } else { props = join(root, 'out', `feature-${what}.props.json`); writeFileSync(props, JSON.stringify({ reel: what })); name = `feature-${what}`; } for (const format of formats) { const id = `${kind === 'change' ? 'Change' : 'Feature'}-${format}`; const out = join(root, 'out', `${name}-${format}.mp4`); const r = spawnSync( join(root, 'node_modules/.bin/remotion'), ['render', 'video/index.ts', id, out, `--props=${props}`, '--crf=18'], { cwd: root, stdio: 'inherit' } ); if (r.status !== 0) process.exit(r.status ?? 1); }