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 authorization header 帶入即可。把它填進 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 呼叫就能上線

拿一把免費金鑰,五分鐘內完成你的第一次呼叫。