ffmpeg trên Cloudflare Workers

Chạy ffmpeg trên Cloudflare Workers bằng cách gọi nó, không phải đóng gói nó.

Workers chạy trong V8 isolate — không có filesystem, không có binary gốc, giới hạn CPU rất ngặt. Worker của bạn gửi cho Fotovid một URL qua HTTPS; quá trình encode chạy bên ngoài isolate và trả về dưới dạng link được lưu trữ sẵn, nên nó không hề tính vào ngân sách CPU của bạn.

export default {
  async fetch(req: Request, env: { FOTOVID_API_KEY: string }): Promise<Response> {
    const { videoUrl, logoUrl } = await req.json();

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

Vì sao Worker của bạn bó tay với ffmpeg

Cloudflare Workers không chạy trong container — chúng chạy bên trong V8 isolate. Không có filesystem để ghi file tạm, không có cách nào để gọi ra một binary gốc, và giới hạn thời gian CPU cho mỗi request rất ngặt nghèo. Binary ffmpeg đơn giản là không thể tồn tại ở đó. Bản build WASM về mặt kỹ thuật thì load được, nhưng nó bị giới hạn bởi ngân sách bộ nhớ và CPU của isolate rồi chết ngay khi xử lý bất cứ thứ gì vượt quá một đoạn clip đơn giản. Một API bên ngoài là con đường khả thi duy nhất.

  • Không có filesystem: ffmpeg cần file tạm để đọc input và ghi output — Workers không cung cấp file tạm nào cả.
  • Không có binary gốc: bạn không thể cài đặt hay chạy binary ffmpeg trong V8 isolate.
  • ffmpeg bản WASM load được nhưng bị giới hạn bởi bộ nhớ và CPU của isolate — nó bị đơ hoặc timeout khi xử lý video thực tế.
  • Ngân sách CPU cho mỗi request quá ngặt khiến bất kỳ tác vụ transcode nào cũng bất khả thi ngay từ đầu.

Cách các team từng chạy ffmpeg trên Cloudflare Workers

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

OptionWhat it costs youVerdict
Đóng gói ffmpeg vào function Cloudflare Workers của bạnWorkers hoàn toàn không thể chạy binary gốc
Tự host một container hoặc VMChi phí chạy liên tục cộng thêm việc vá lỗi, mở rộng và giám sát
Chạy một hàng đợi + workerHạ tầng mới hoàn toàn: hàng đợi, worker, cơ chế retry, xử lý dead-letter
Transcode ngay trên trình duyệt (WASM)Chậm, ngốn nhiều bộ nhớ, và 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 gì cả
How it works

Lệnh gọi đầu tiên của bạn chỉ 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 sẽ nhận được token dạng Authorization: Bearer p6_<key_id>:<secret> để xác thực mọi lệnh gọi tới https://api.fotovid.co. Không cần hạ tầng, không cần build ffmpeg — chỉ cần một header.

  2. 2
    POST video của bạn từ Worker

    Gọi POST /v1/video/watermark với envelope tiêu chuẩn: một source_url trỏ tới URL HTTPS của video đầu vào, và một object params — đặt type là image, text, hoặc combo, cùng với position (ví dụ bottom-right), opacity và scale. Đây chỉ là một lệnh fetch thuần túy từ bên trong Worker, nên nó khớp hoàn hảo với mô hình request của isolate.

  3. 3
    Sử dụng URL kết quả đã được lưu trữ sẵn

    Fotovid trả về JSON phẳng: { id, type, url, expires_at, duration }. url trỏ tới video đã gắn watermark hoàn chỉnh của bạn trên hạ tầng lưu trữ của Fotovid. Đưa thẳng nó cho client của bạn, hoặc sao chép vào bucket riêng của bạn để giữ bản lưu vĩnh viễn — kết quả được lưu trữ này chỉ mang tính tạm thời.

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.