feat: Implement Remotion video rendering API with TTS, word timings, and Docker pre-bundling.

This commit is contained in:
Michael committed 2026-03-24 13:33:18 +01:00
1 parent d98d43cd06
commit e472e05a3b
3 files changed
+33 -5

No files matched your search

+8 -1
View File
@@ -63,7 +63,14 @@ ENV NODE_OPTIONS="--max-old-space-size=4096"
RUN npm run build
# Nettoyer les fichiers inutiles pour réduire la taille
RUN rm -rf client node_modules/.cache
# On garde client/src/remotion car le serveur en a besoin au runtime pour le bundling
RUN rm -rf client/node_modules \
client/.vite \
node_modules/.cache \
/tmp/remotion-*
# Pré-bundler la composition Remotion pendant le build (speedup au premier rendu)
RUN node scripts/prebundle-remotion.js || true
# Exposer le port de l'application
EXPOSE 5555
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/env node
// Pre-bundle Remotion composition during Docker build.
// This warms up the Webpack cache so the first user render is fast.
const { bundle } = require('@remotion/bundler');
const path = require('path');
bundle({ entryPoint: path.resolve(__dirname, '../client/src/remotion/index.ts') })
.then(loc => console.log('✅ Remotion pre-bundle OK:', loc))
.catch(e => { console.warn('⚠️ Remotion pre-bundle skipped:', e.message); process.exit(0); });
+16 -4
View File
@@ -23,6 +23,20 @@ const storage = multer.diskStorage({
const upload = multer({ storage });
/** Cached Remotion bundle URL — only bundle once per process lifecycle */
let remotionBundleCache: string | null = null;
async function getBundle(): Promise<string> {
if (remotionBundleCache) return remotionBundleCache;
// Resolve relative to this file so it works in Docker and locally
// __dirname = server/routes, so ../.. → project root → client/src/remotion/index.ts
const entryPoint = path.resolve(__dirname, "../../client/src/remotion/index.ts");
console.log("📦 Bundling Remotion from:", entryPoint);
remotionBundleCache = await bundle({ entryPoint });
console.log("📦 Bundle cached at:", remotionBundleCache);
return remotionBundleCache;
}
/**
* Strips hashtags and emojis from text for TTS synthesis.
* Visual display keeps the full text.
@@ -138,10 +152,8 @@ remotionRouter.post("/render", upload.array("images", 4), async (req, res) => {
}
}
console.log("🎬 Bundling Remotion project...");
const bundleLocation = await bundle({
entryPoint: path.resolve(process.cwd(), "client/src/remotion/index.ts"),
});
console.log("🎬 Getting Remotion bundle (cached)...");
const bundleLocation = await getBundle();
const inputProps = { images: imageUrls, overlayText, audioUrl, wordTimings };