ffmpeg su Vercel si rompe al deploy — chiama un'API che non si rompe.
Funzionava su localhost, poi si è rotto proprio al deploy. Non è il tuo codice, è il runtime. Punta la tua funzione Vercel su Fotovid: invii un source URL, Fotovid ti restituisce il media renderizzato.
// 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 });
}Perché ffmpeg si rompe su Vercel
Vercel è un ottimo posto per far girare la tua app e un ambiente ostile per far girare ffmpeg. Le funzioni serverless Node limitano il bundle non compresso a 250MB, e ffmpeg più i suoi codec supera quel limite ancor prima che venga contato il tuo codice. Se passi al runtime Edge per aggirare il limite di dimensione, perdi completamente child_process, quindi non c'è modo di lanciare un binario. Anche quando una build riesce a passare, il timeout della funzione (10s su Hobby, limitato su Pro) interrompe qualsiasi encode reale a metà lavoro. ffmpeg-static e fluent-ffmpeg funzionano in locale e falliscono al deploy esattamente per questi motivi.
- Limite di 250MB per funzione non compressa: ffmpeg più i codec non ci stanno in un bundle serverless Node
- Il runtime Edge non ha API Node né child_process, quindi non puoi lanciare un binario
- I timeout delle funzioni (10s su Hobby, limitati su Pro) tagliano gli encode lunghi a metà esecuzione
- ffmpeg-static e fluent-ffmpeg funzionano su localhost e si rompono nel momento in cui fai il deploy
Come i team provano a far girare ffmpeg su Vercel
Prima di Fotovid queste erano le opzioni — ognuna è lavoro che preferiresti non doverti accollare.
| Option | What it costs you | Verdict |
|---|---|---|
| Impacchettare ffmpeg nella tua funzione Vercel | Supera il limite di 250MB per funzione; Edge non ha child_process | |
| Self-hosting di un container o una VM | Costo always-on più patching, scaling e monitoraggio | |
| Gestire una coda di job + worker | Nuova infrastruttura: una coda, worker, retry, gestione dead-letter | |
| Transcodificare nel browser (WASM) | Lento, affamato di memoria, e va in crash su mobile | |
| Chiamare l'API di Fotovid | Una richiesta HTTPS; niente da eseguire, impacchettare o scalare |
La tua prima chiamata in tre passaggi
- 1Ottieni una API key gratuita
Registrati e crea una key, nessuna carta richiesta. Ricevi un token nel formato p6_<key_id>:<secret> da passare come header di autorizzazione Bearer. Inseriscilo tra le variabili d'ambiente del tuo progetto Vercel così la tua funzione può leggerlo a runtime.
- 2Invia il tuo video con POST all'endpoint della filigrana
Dalla tua funzione Vercel, chiama POST /v1/video/watermark su https://api.fotovid.co con l'envelope standard: una source_url che punta al tuo video di input, più un oggetto params che descrive l'overlay (una filigrana a immagine o testo, la sua posizione, opacità e scala). Nessun binario, nessun bundle, nessun encode in esecuzione dentro la tua funzione. Fotovid esegue il lavoro di ffmpeg sulla propria infrastruttura, quindi il tuo timeout non entra mai in gioco.
- 3Usa l'URL hosted restituito
La risposta torna come JSON piatto con un id, type, un url ospitato da fotovid per il video finito, e un expires_at. Salva una tua copia di quel file, oppure passa l'URL direttamente al tuo frontend. Lo stesso envelope funziona per il resto dell'API: trim, extract-audio, extract-cover, probe e altro.
Domande frequenti
Rilascialo con una sola chiamata API
Prendi una chiave gratuita e fai la tua prima chiamata in meno di cinque minuti.
