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 之前,你只有這些選項 —— 每一個都是你不會想自己扛的工作。
| Option | What it costs you | Verdict |
|---|---|---|
| 把 ffmpeg 打包進 Vercel 函式 | 遠遠超過 250MB 的函式體積上限;Edge 又沒有 child_process | |
| 自架容器或虛擬機 | 全天候開著的機器成本,外加修補更新、擴充與監控 | |
| 自建任務佇列 + worker | 多一整套基礎設施:佇列、worker、重試、死信處理 | |
| 在瀏覽器裡轉檔(WASM) | 又慢又吃記憶體,在手機上還會直接當掉 | |
| 呼叫 Fotovid API | 一個 HTTPS 請求;沒有東西要跑、要打包、要擴充 |
三個步驟完成第一次呼叫
- 1取得免費 API 金鑰
註冊後建立一組金鑰,不需要信用卡。你會拿到一組格式為 p6_<key_id>:<secret> 的權杖,以 Bearer authorization header 帶入即可。把它填進 Vercel 專案的環境變數,函式執行時就讀得到。
- 2把影片 POST 到浮水印端點
在你的 Vercel 函式裡,對 https://api.fotovid.co 呼叫 POST /v1/video/watermark,帶上統一的請求格式:一個指向來源影片的 source_url,加上描述疊加內容的 params 物件(圖片或文字浮水印、位置、不透明度與縮放比例)。不用二進位檔、不用打包,函式裡也不會跑任何編碼。ffmpeg 的工作由 Fotovid 在自己的基礎設施上完成,你的函式逾時根本輪不到上場。
- 3直接使用回傳的託管 URL
回應是扁平的 JSON,包含 id、type、指向成品影片的 fotovid 託管 url,以及 expires_at。你可以自己另存一份檔案,或把這個 URL 直接交給前端。API 其餘功能也吃同一套請求格式:trim、extract-audio、extract-cover、probe 等等。
