import path from "path"; import { bundle } from "@remotion/bundler"; import { renderMedia, selectComposition } from "@remotion/renderer"; export * from "./compositions/index"; let cachedBundlePath: string | null = null; export async function getBundlePath(): Promise { if (cachedBundlePath) { return cachedBundlePath; } const entryPoint = path.resolve(__dirname, "Root.tsx"); cachedBundlePath = await bundle({ entryPoint }); return cachedBundlePath; } export interface RenderPresentationOptions { serveUrl: string; input: Record; onProgress: (progress: number) => void; browserExecutable?: string; } export interface RenderPresentationResult { buffer: Buffer; durationInFrames: number; fps: number; inputProps: Record; } export async function renderPresentationComposition( opts: RenderPresentationOptions, ): Promise { const { serveUrl, input, onProgress, browserExecutable } = opts; const compositionId = input["videoType"] === "demo" ? "DemoVideo" : "PitchDeck"; const composition = await selectComposition({ serveUrl, id: compositionId, inputProps: input, ...(browserExecutable ? { browserExecutable } : {}), }); const result = await renderMedia({ composition, serveUrl, codec: "h264", concurrency: 1, inputProps: input, outputLocation: null, ...(browserExecutable ? { browserExecutable } : {}), onProgress: ({ progress }) => { onProgress(Math.round(progress * 100)); }, }); if (!result.buffer) { throw new Error("renderMedia returned null buffer"); } return { buffer: result.buffer, durationInFrames: composition.durationInFrames, fps: composition.fps, inputProps: input, }; }