ffmpeg sur Vercel casse au déploiement — appelle une API qui ne casse pas.
Ça marchait en local, puis tout a cassé au déploiement. Ce n'est pas ton code, c'est le runtime. Fais pointer ta fonction Vercel vers Fotovid : elle envoie une URL source, Fotovid renvoie le média généré.
// app/api/watermark/route.ts
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { videoUrl, logoUrl } = await req.json();
const res = await fetch("https://api.fotovid.co/v1/video/watermark", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FOTOVID_API_KEY!}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
source_url: videoUrl,
params: { type: "image", watermark_image_url: logoUrl, position: "bottom-right" },
}),
});
const { url } = await res.json();
return NextResponse.json({ url });
}Pourquoi ffmpeg casse sur Vercel
Vercel est un excellent endroit pour héberger ton app, et un terrain hostile pour faire tourner ffmpeg. Les fonctions serverless Node plafonnent le bundle décompressé à 250 Mo, et ffmpeg avec ses codecs dépasse cette limite avant même que ton propre code ne soit compté. Passer au runtime Edge pour contourner la limite de taille te fait perdre child_process entièrement, donc impossible de lancer un binaire. Même quand un build passe de justesse, le timeout de la fonction (10 s sur Hobby, plafonné sur Pro) coupe court à tout encodage réel en cours de route. ffmpeg-static et fluent-ffmpeg passent en local et échouent au déploiement, exactement pour ces raisons.
- Limite de 250 Mo pour un bundle de fonction décompressé : ffmpeg et ses codecs n'entrent pas dans un bundle serverless Node
- Le runtime Edge n'a pas d'API Node ni de child_process, donc impossible de lancer un binaire
- Les timeouts de fonction (10 s sur Hobby, plafonnés sur Pro) coupent les encodages longs en cours de route
- ffmpeg-static et fluent-ffmpeg fonctionnent en local et cassent dès le déploiement
Comment les équipes s'y prennent pour faire tourner ffmpeg sur Vercel
Avant Fotovid, c'était les options — et chacune représente du travail dont tu te passerais bien.
| Option | What it costs you | Verdict |
|---|---|---|
| Empaqueter ffmpeg dans ta fonction Vercel | Dépasse la limite de 250 Mo de la fonction ; Edge n'a pas de child_process | |
| Auto-héberger un conteneur ou une VM | Coût permanent, plus patchs, mise à l'échelle et supervision | |
| Mettre en place une file d'attente de jobs + workers | Nouvelle infrastructure : une file d'attente, des workers, des retries, la gestion des dead letters | |
| Transcoder dans le navigateur (WASM) | Lent, gourmand en mémoire, et plante sur mobile | |
| Appeler l'API Fotovid | Une seule requête HTTPS ; rien à faire tourner, packager ou scaler |
Ton premier appel en trois étapes
- 1Récupère une clé API gratuite
Inscris-toi et crée une clé, aucune carte bancaire requise. Tu obtiens un token au format p6_<key_id>:<secret> à passer en en-tête d'autorisation Bearer. Ajoute-le aux variables d'environnement de ton projet Vercel pour que ta fonction puisse le lire au runtime.
- 2Envoie ta vidéo en POST vers l'endpoint watermark
Depuis ta fonction Vercel, appelle POST /v1/video/watermark sur https://api.fotovid.co avec l'enveloppe standard : une source_url pointant vers ta vidéo source, plus un objet params décrivant l'overlay (un watermark image ou texte, sa position, son opacité et son échelle). Aucun binaire, aucun bundle, aucun encodage ne tourne dans ta fonction. Fotovid effectue le travail ffmpeg sur sa propre infrastructure, donc ton timeout n'entre jamais en jeu.
- 3Utilise l'URL hébergée que Fotovid te renvoie
La réponse arrive en JSON plat avec un id, un type, une url hébergée par fotovid pour la vidéo finale, et un expires_at. Stocke ta propre copie du fichier, ou transmets directement l'URL à ton frontend. La même enveloppe fonctionne pour le reste de l'API : trim, extract-audio, extract-cover, probe, et plus encore.
Questions fréquentes
Déploie-le avec un seul appel API
Récupère une clé gratuite et fais ton premier appel en moins de cinq minutes.
