ffmpeg trên Netlify Functions

ffmpeg trên Netlify Functions: quá lớn để đóng gói, đã có Fotovid host giúp bạn.

Netlify Functions chạy trên AWS Lambda, nên ffmpeg vượt xa cả giới hạn dung lượng đóng gói lẫn timeout mặc định. Hãy giao việc này cho Fotovid: gửi một request, nhận về một URL kết quả sẵn dùng — luôn nằm trong mọi giới hạn timeout.

// netlify/functions/watermark.mts
export default async (req: Request) => {
  const { videoUrl, logoUrl } = await req.json();

  const res = await fetch("https://api.fotovid.co/v1/video/watermark", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${Netlify.env.get("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 Response.json({ url });
};

Vì sao ffmpeg trên Netlify luôn thất bại

Netlify Functions thực thi trên AWS Lambda, và đó chính là nơi ffmpeg vấp phải giới hạn. Một binary ffmpeg tĩnh quá lớn so với giới hạn đóng gói ~50MB (nén) / 250MB (giải nén), nên deploy hoặc thất bại, hoặc binary âm thầm không được ship. Ngay cả khi bạn nhét vừa nó, timeout mặc định 10s của function cũng giết chết mọi tác vụ transcode thực sự — background function cho bạn thêm 26s, vẫn không đủ cho phần lớn công việc xử lý video. Đây chính là cái bẫy kinh điển 'chạy ngon trên laptop, timeout khi lên production'.

  • Binary ffmpeg cùng các thư viện vượt giới hạn đóng gói 250MB (giải nén) của Lambda
  • Timeout mặc định 10s (26s với background) giết chết các tác vụ transcode thực sự giữa chừng
  • Cold start và việc vật lộn với layer làm tăng độ trễ và gây khó khăn khi đóng gói
  • Chạy thành công ở local không đảm bảo tái hiện được trên function đã deploy

Những cách các team từng thử để chạy ffmpeg trên Netlify

Trước khi có Fotovid, đây là những lựa chọn — mỗi cách đều là việc bạn chẳng muốn tự ôm vào người.

OptionWhat it costs youVerdict
Đóng gói ffmpeg vào Netlify function của bạnVượt giới hạn đóng gói 250MB và dính timeout 10s của function
Tự host một container hoặc VMChi phí chạy liên tục, cộng thêm vá lỗi, mở rộng quy mô và giám sát
Chạy một job queue + workerHạ tầng mới: queue, worker, cơ chế retry, xử lý dead-letter
Transcode ngay trong trình duyệt (WASM)Chậm, ngốn bộ nhớ, và hay crash trên mobile
Gọi Fotovid APIChỉ một request HTTPS; không cần chạy, đóng gói hay mở rộng quy mô gì cả
How it works

Lệnh gọi đầu tiên của bạn trong ba bước

  1. 1
    Lấy một API key miễn phí

    Đăng ký và tạo một key. Bạn xác thực bằng header Authorization: Bearer p6_<key_id>:<secret> — không cần binary, không cần Lambda layer, không có gì phải đóng gói vào Netlify Function của bạn.

  2. 2
    POST video của bạn tới endpoint hình mờ

    Từ bên trong Netlify Function của bạn, gọi POST /v1/video/watermark trên https://api.fotovid.co. Gửi envelope tiêu chuẩn: một source_url trỏ đến video đầu vào, cùng một object params — đặt type là image, text hoặc combo, sau đó chọn một position như bottom-right, cùng opacity, scale và padding. Fotovid xử lý toàn bộ phần ffmpeg bên ngoài platform của bạn, nên function của bạn chỉ cần gửi một request HTTPS nhanh, thay vì tự chạy một binary vốn không thể đóng gói nổi.

  3. 3
    Dùng URL kết quả đã được host sẵn

    Response là JSON phẳng gồm id, type, url và expires_at. url trỏ đến video đã hoàn thiện, được host trên Fotovid. Trả nó về cho client của bạn hoặc lưu lại một bản riêng — vì kết quả chỉ được host tạm thời, hãy tải về và lưu trữ lại ở bất kỳ đâu bạn đang lưu asset.

Các câu hỏi thường gặp

Triển khai chỉ với một lệnh gọi API

Lấy một key miễn phí và thực hiện lệnh gọi đầu tiên trong chưa đầy năm phút.