Vercel 上的 ffmpeg

ffmpeg 在 Vercel 上一部署就挂——改用一个不会挂的 API。

本地跑得好好的,一部署就挂了。问题不在你的代码,而在运行时。让你的 Vercel 函数指向 Fotovid:函数发出一个源文件 URL,Fotovid 返回处理好的媒体文件。

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

ffmpeg 为什么在 Vercel 上跑不起来

Vercel 很适合跑你的应用,却对 ffmpeg 处处不友好。Node serverless 函数把解压后的打包产物限制在 250MB 以内,而 ffmpeg 加上它的编解码器,还没算上你自己的代码就已经远远超标。想切到 Edge Runtime 来绕开体积限制,你就彻底失去了 child_process,根本没有办法启动任何二进制。就算构建侥幸通过,函数超时(Hobby 上是 10s,Pro 上也有上限)也会把任何真实的编码任务拦腰截断。ffmpeg-static 和 fluent-ffmpeg 在本地一路顺利,一部署就失败,原因正在于此。

  • 解压后 250MB 的函数上限:ffmpeg 加上编解码器塞不进 Node serverless 打包产物
  • Edge Runtime 没有 Node API,也没有 child_process,你无法启动任何二进制
  • 函数超时(Hobby 10s,Pro 也有上限)会让耗时长的编码中途被掐断
  • ffmpeg-static 和 fluent-ffmpeg 在本地能跑,一部署就挂

团队在 Vercel 上跑 ffmpeg 的几种尝试

在 Fotovid 出现之前,你只有这几个选择——每一个都是你不想自己扛下来的活儿。

OptionWhat it costs youVerdict
把 ffmpeg 打包进 Vercel 函数远远超出 250MB 函数上限;Edge 又没有 child_process
自建容器或虚拟机常驻成本,外加打补丁、扩缩容和监控
搭一套任务队列 + worker多出一整套基础设施:队列、worker、重试、死信处理
在浏览器里转码(WASM)又慢又吃内存,在手机上还会崩溃
调用 Fotovid API一次 HTTPS 请求;没有东西要运维、要打包、要扩容
How it works

三步完成第一次调用

  1. 1
    免费拿一个 API 密钥

    注册并创建密钥,无需绑卡。你会拿到一个形如 p6_<key_id>:<secret> 的令牌,通过 Bearer 授权头传入。把它写进 Vercel 项目的环境变量,函数在运行时就能读到。

  2. 2
    把视频 POST 到水印端点

    在你的 Vercel 函数里,向 https://api.fotovid.co 上的 POST /v1/video/watermark 发起调用,用的是统一的请求结构:一个指向输入视频的 source_url,再加上描述叠加内容的 params 对象(图片或文字水印、位置、不透明度和缩放比例)。不用二进制,不用打包,函数内部也不跑任何编码。ffmpeg 的活儿由 Fotovid 在自己的基础设施上完成,你的函数超时限制根本不会成为问题。

  3. 3
    直接使用返回的托管 URL

    响应是扁平的 JSON,包含 id、type、指向成片的 fotovid 托管 url,以及 expires_at。你可以自己存一份文件副本,也可以把 URL 直接交给前端。API 的其余能力用的是同一套请求结构:trim、extract-audio、extract-cover、probe 等等。

常见问题

一次 API 调用即可上线

领一个免费密钥,五分钟内完成你的第一次调用。