From 42e17471785c71cb3011790d28b8b898d12a1f71 Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Fri, 8 May 2026 16:50:45 +0800 Subject: [PATCH] feat(videos): add batch render script for all promo compositions --- apps/videos/scripts/render-all.mjs | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 apps/videos/scripts/render-all.mjs diff --git a/apps/videos/scripts/render-all.mjs b/apps/videos/scripts/render-all.mjs new file mode 100644 index 00000000..ac15ad5c --- /dev/null +++ b/apps/videos/scripts/render-all.mjs @@ -0,0 +1,49 @@ +import { bundle } from "@remotion/bundler"; +import { renderMedia, selectComposition } from "@remotion/renderer"; +import { enableTailwind } from "@remotion/tailwind"; +import fs from "node:fs"; +import path from "node:path"; + +const COMPOSITIONS = [ + { id: "XLaunchVideo", slug: "x-launch" }, + { id: "ProductDemo", slug: "product-demo" }, + { id: "PromoTeaser", slug: "promo-teaser-square" }, + { id: "PromoTeaserVertical", slug: "promo-teaser-vertical" }, +]; + +const OUTPUT_DIR = path.resolve("./out"); +fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + +console.log("Bundling..."); +const bundleLocation = await bundle({ + entryPoint: "./src/index.ts", + webpackOverride: (config) => enableTailwind(config), +}); +console.log("Bundle complete.\n"); + +for (const comp of COMPOSITIONS) { + console.log(`Rendering ${comp.id}...`); + const composition = await selectComposition({ + serveUrl: bundleLocation, + id: comp.id, + }); + + await renderMedia({ + composition, + serveUrl: bundleLocation, + codec: "h264", + crf: 20, + pixelFormat: "yuv420p", + imageFormat: "jpeg", + concurrency: 4, + outputLocation: path.join(OUTPUT_DIR, `${comp.slug}.mp4`), + onProgress: ({ progress }) => { + const pct = Math.round(progress * 100); + if (pct % 10 === 0) process.stdout.write(`\r ${pct}%`); + }, + }); + + console.log(`\r Done: ${comp.slug}.mp4`); +} + +console.log(`\nAll ${COMPOSITIONS.length} videos rendered to ${OUTPUT_DIR}`);