From f7531e19aa4d00116d0326359f126b11092565c8 Mon Sep 17 00:00:00 2001 From: SnapOtter Date: Fri, 8 May 2026 17:17:53 +0800 Subject: [PATCH] feat(videos): add render-all script for dual-format batch rendering --- apps/videos/scripts/render-all.mjs | 72 ++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/apps/videos/scripts/render-all.mjs b/apps/videos/scripts/render-all.mjs index ac15ad5c..43cd8a42 100644 --- a/apps/videos/scripts/render-all.mjs +++ b/apps/videos/scripts/render-all.mjs @@ -1,49 +1,93 @@ import { bundle } from "@remotion/bundler"; -import { renderMedia, selectComposition } from "@remotion/renderer"; +import { renderMedia, renderStill, selectComposition } from "@remotion/renderer"; import { enableTailwind } from "@remotion/tailwind"; import fs from "node:fs"; import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const COMPOSITIONS = [ - { id: "XLaunchVideo", slug: "x-launch" }, - { id: "ProductDemo", slug: "product-demo" }, - { id: "PromoTeaser", slug: "promo-teaser-square" }, - { id: "PromoTeaserVertical", slug: "promo-teaser-vertical" }, + { id: "PrivacyPromise", slug: "privacy-promise", posterFrame: 140 }, + { id: "ToolGalaxy", slug: "tool-galaxy", posterFrame: 450 }, + { id: "OneCommand", slug: "one-command", posterFrame: 300 }, + { id: "AiMagicReel", slug: "ai-magic-reel", posterFrame: 190 }, + { id: "FormatUniverse", slug: "format-universe", posterFrame: 90 }, + { id: "PipelineFlow", slug: "pipeline-flow", posterFrame: 260 }, + { id: "FloatingTools", slug: "floating-tools", posterFrame: 60 }, + { id: "BrandGradient", slug: "brand-gradient", posterFrame: 0 }, + { id: "The48", slug: "the-48", posterFrame: 420 }, + { id: "CloudVsLocal", slug: "cloud-vs-local", posterFrame: 380 }, ]; -const OUTPUT_DIR = path.resolve("./out"); +const OUTPUT_DIR = path.resolve(__dirname, "../../landing/public/videos"); fs.mkdirSync(OUTPUT_DIR, { recursive: true }); -console.log("Bundling..."); +console.log("Bundling Remotion project..."); const bundleLocation = await bundle({ - entryPoint: "./src/index.ts", + entryPoint: path.resolve(__dirname, "../src/index.ts"), webpackOverride: (config) => enableTailwind(config), }); console.log("Bundle complete.\n"); -for (const comp of COMPOSITIONS) { - console.log(`Rendering ${comp.id}...`); +const total = COMPOSITIONS.length; + +for (let i = 0; i < total; i++) { + const comp = COMPOSITIONS[i]; + console.log(`[${i + 1}/${total}] ${comp.id}`); + const composition = await selectComposition({ serveUrl: bundleLocation, id: comp.id, }); + // MP4 (H.264, CRF 22) + console.log(" Rendering MP4 (H.264)..."); await renderMedia({ composition, serveUrl: bundleLocation, codec: "h264", - crf: 20, + crf: 22, 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}%`); + if (pct % 10 === 0) process.stdout.write(`\r MP4: ${pct}%`); }, }); + console.log(`\r MP4: done`); - console.log(`\r Done: ${comp.slug}.mp4`); + // WebM (VP9, CRF 31) + console.log(" Rendering WebM (VP9)..."); + await renderMedia({ + composition, + serveUrl: bundleLocation, + codec: "vp9", + crf: 31, + imageFormat: "jpeg", + concurrency: 4, + outputLocation: path.join(OUTPUT_DIR, `${comp.slug}.webm`), + onProgress: ({ progress }) => { + const pct = Math.round(progress * 100); + if (pct % 10 === 0) process.stdout.write(`\r WebM: ${pct}%`); + }, + }); + console.log(`\r WebM: done`); + + // Poster frame (WebP still) + console.log(" Rendering poster frame..."); + await renderStill({ + composition, + serveUrl: bundleLocation, + frame: comp.posterFrame, + imageFormat: "webp", + output: path.join(OUTPUT_DIR, `${comp.slug}-poster.webp`), + }); + console.log(" Poster: done\n"); } -console.log(`\nAll ${COMPOSITIONS.length} videos rendered to ${OUTPUT_DIR}`); +console.log( + `All ${total} compositions rendered (MP4 + WebM + poster) to ${OUTPUT_DIR}`, +);