~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
46 lines · 1.6 KB Raw History
// Renders a video into out/, in each shape asked for (wide, square, tall):
//
//   node render.mjs change out/stories/<rkey>.json [--formats wide,tall]
//   node render.mjs feature <reel> [--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 <story.json> | feature <reel> [--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);
}