From dc4671dee6f5b28df955c07a99efa68b014d1b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Wed, 27 May 2026 20:20:21 -0400 Subject: [PATCH] fix(studio): add FFmpeg pre-flight check before render (#1100) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(studio): add FFmpeg pre-flight check before starting render Studio renders now fail fast with a 422 and an actionable FFmpeg install hint instead of burning through the entire capture pipeline before hitting "spawn ffmpeg ENOENT" at encode. * fix(studio): address review — use 503, memoize FFmpeg lookup --- packages/cli/src/server/studioServer.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/cli/src/server/studioServer.ts b/packages/cli/src/server/studioServer.ts index 5e415f9ab..8c7ae9b0c 100644 --- a/packages/cli/src/server/studioServer.ts +++ b/packages/cli/src/server/studioServer.ts @@ -508,6 +508,22 @@ export function createStudioServer(options: StudioServerOptions): StudioServer { }); }); + // ── Pre-flight checks for render ──────────────────────────────────────── + // Intercept render requests before they reach the shared API so we can + // fail fast with an actionable hint instead of burning through the entire + // capture pipeline before hitting "spawn ffmpeg ENOENT" at encode. + let cachedFFmpegPath: string | undefined; + app.post("/api/projects/:id/render", async (c, next) => { + const { findFFmpeg, getFFmpegInstallHint } = await import("../browser/ffmpeg.js"); + if (!cachedFFmpegPath) { + cachedFFmpegPath = findFFmpeg(); + } + if (!cachedFFmpegPath) { + return c.json({ error: "FFmpeg not found", hint: getFFmpegInstallHint() }, 503); + } + return next(); + }); + // Mount the shared studio API at /api. // Use fetch() forwarding (not .route()) so the sub-app sees paths without // the /api prefix — the shared module's path extraction uses c.req.path.