ffmpeg en Vercel

ffmpeg en Vercel falla al desplegar — llama a una API que no falla.

Funcionaba en localhost y falló justo al desplegar. No es tu código, es el runtime. Apunta tu función de Vercel a Fotovid: envía una URL de origen y Fotovid te devuelve el archivo procesado.

// 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 });
}

Por qué ffmpeg falla en Vercel

Vercel es un gran lugar para ejecutar tu app y uno hostil para ejecutar ffmpeg. Las funciones serverless de Node limitan el paquete sin comprimir a 250MB, y ffmpeg junto con sus códecs supera ese límite antes de que se cuente tu propio código. Si cambias al runtime de Edge para evitar el límite de tamaño, pierdes child_process por completo, así que no hay forma de lanzar un binario. Incluso cuando un build logra pasar, el timeout de la función (10s en Hobby, acotado en Pro) corta cualquier codificación real a mitad de camino. ffmpeg-static y fluent-ffmpeg funcionan en local y fallan al desplegar exactamente por estas razones.

  • Límite de 250MB sin comprimir por función: ffmpeg más los códecs no caben en un paquete serverless de Node
  • El runtime de Edge no tiene APIs de Node ni child_process, así que no puedes lanzar un binario
  • Los timeouts de función (10s en Hobby, acotado en Pro) cortan las codificaciones largas a mitad de ejecución
  • ffmpeg-static y fluent-ffmpeg funcionan en localhost y fallan justo al desplegar

Formas en que los equipos intentan ejecutar ffmpeg en Vercel

Antes de Fotovid, estas eran las opciones — cada una es trabajo que preferirías no tener que mantener.

OptionWhat it costs youVerdict
Empaquetar ffmpeg dentro de tu función de VercelSupera el límite de 250MB por función; Edge no tiene child_process
Auto-alojar un contenedor o VMCosto permanente más parches, escalado y monitoreo
Montar una cola de trabajos + workerInfraestructura nueva: una cola, workers, reintentos, manejo de dead-letter
Transcodificar en el navegador (WASM)Lento, exige mucha memoria y falla en móvil
Llamar a la API de FotovidUna sola solicitud HTTPS; nada que ejecutar, empaquetar ni escalar
How it works

Tu primera llamada en tres pasos

  1. 1
    Consigue una API key gratis

    Regístrate y crea una key, sin necesidad de tarjeta. Obtienes un token con el formato p6_<key_id>:<secret> que pasas como cabecera de autorización Bearer. Añádelo a las variables de entorno de tu proyecto de Vercel para que tu función pueda leerlo en tiempo de ejecución.

  2. 2
    Envía tu video con POST al endpoint de marca de agua

    Desde tu función de Vercel, llama a POST /v1/video/watermark en https://api.fotovid.co con el envelope estándar: una source_url que apunta a tu video de entrada, más un objeto params que describe la superposición (una marca de agua de imagen o texto, su posición, opacidad y escala). Sin binario, sin paquete, sin codificación ejecutándose dentro de tu función. Fotovid hace el trabajo de ffmpeg en su propia infraestructura, así que tu timeout nunca entra en juego.

  3. 3
    Usa la URL alojada que te devuelven

    La respuesta llega como JSON plano con un id, type, una url alojada por fotovid para el video terminado, y un expires_at. Guarda tu propia copia de ese archivo, o pasa la URL directo a tu frontend. El mismo envelope funciona para el resto de la API: trim, extract-audio, extract-cover, probe y más.

Preguntas frecuentes

Lánzalo con una sola llamada a la API

Consigue una key gratis y haz tu primera llamada en menos de cinco minutos.