ffmpeg en Supabase Edge Functions, delegado a una sola llamada HTTPS.
Las Edge Functions corren sobre Deno, así que no hay child_process con el que lanzar el binario de ffmpeg. Conserva tu función, delega el encoding a una llamada HTTPS y recibe de vuelta la URL del archivo terminado.
// supabase/functions/watermark/index.ts
Deno.serve(async (req) => {
const { videoUrl, logoUrl } = await req.json();
const res = await fetch("https://api.fotovid.co/v1/video/watermark", {
method: "POST",
headers: {
Authorization: `Bearer ${Deno.env.get("FOTOVID_API_KEY")}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
source_url: videoUrl, // a Supabase Storage signed URL works here
params: { type: "image", watermark_image_url: logoUrl, position: "bottom-right" },
}),
});
const { url } = await res.json();
return Response.json({ url });
});Por qué ffmpeg no funciona en tu Edge Function
Las Supabase Edge Functions se ejecutan en el runtime de Deno, que no tiene API de child_process ni de subprocess — así que no hay nada con qué lanzar el binario de ffmpeg, ni aunque lo incluyas en el paquete. Además, los límites de CPU y de tiempo de ejecución están pensados para lógica ligera de request, no para el trabajo sostenido de segundos a minutos que requiere el encoding de medios. Un trigger de Storage es el lugar perfecto para *iniciar* un job en cuanto llega un archivo, pero el transcoding en sí tiene que ocurrir donde pueda correr un encoder de verdad.
- Sin child_process / subprocess en Deno — no puedes ejecutar el binario de ffmpeg
- Los límites de CPU y de tiempo de ejecución apuntan a lógica rápida, no a encoding de medios
- Los triggers de Storage son ideales para arrancar un job, pero el trabajo debe correr en otro lugar
- Los builds estáticos de ffmpeg, WASM y los layers chocan con el runtime, no solo con el tamaño
Cómo intentan los equipos correr ffmpeg en Supabase
Antes de Fotovid estas eran las opciones — cada una es trabajo con el que preferirías no cargar.
| Option | What it costs you | Verdict |
|---|---|---|
| Incluir ffmpeg en tu función de Supabase | Deno no tiene child_process — no puedes lanzar el binario | |
| Alojar tú mismo un contenedor o una VM | Costo permanente más parches, escalado y monitoreo | |
| Montar una cola de jobs + worker | Infraestructura nueva: una cola, workers, reintentos, manejo de dead-letter | |
| Transcodificar en el navegador (WASM) | Lento, consume mucha memoria y falla en móvil | |
| Llamar a la API de Fotovid | Un solo request HTTPS; nada que correr, empaquetar ni escalar |
Tu primera llamada en tres pasos
- 1Consigue una API key gratis
Regístrate y crea una API key. Fotovid funciona con créditos de uso — $1 = 100 créditos y la mayoría de las operaciones cuestan 1 crédito — así que puedes conectar la llamada de marca de agua, nuestra operación estrella, y probarla de principio a fin antes de gastar nada.
- 2Llama al endpoint de marca de agua desde tu función
Desde dentro de la misma Edge Function (o del trigger de Storage que se dispara al subir el archivo), haz un POST a https://api.fotovid.co/v1/video/watermark con un header Authorization: Bearer p6_<key_id>:<secret>. Envía el envelope estándar: una source_url que apunte a la URL HTTPS de tu video — una URL firmada de Supabase Storage funciona directamente — más un objeto params que describa el overlay, por ejemplo type image, una watermark_image_url, una position como bottom-right, y una opacity o scale. Tu función solo hace un request HTTPS; Fotovid ejecuta el trabajo de ffmpeg fuera de la plataforma, así que nunca tocas los límites de CPU ni de tiempo de ejecución de Deno.
- 3Usa la URL del resultado alojado
La respuesta es JSON plano: un id, un type y una url que apunta al video terminado, alojado por Fotovid. Devuelve esa url directamente a quien te llamó, o descárgala y guarda tu propia copia en Supabase Storage. Trata la URL alojada como temporal — incluye un expires_at — así que conserva una copia si necesitas que dure a largo plazo.
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.
