ffmpeg trên Deno Deploy

Vì sao ffmpeg không chạy được trên Deno Deploy? Không có subprocess — nên hãy gọi API.

Deno Deploy chạy code của bạn trong các V8 isolate không có subprocess và không có FFI, nên binary ffmpeg không thể khởi chạy. Thay vào đó, hãy gọi Fotovid qua fetch() — quá trình encode diễn ra ở nơi khác và trả về một link https đơn giản trỏ đến file.

Deno.serve(async (req) => {
  const { videoUrl, logoUrl } = await req.json();

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

Mô hình isolate không cho ffmpeg chạy — không cách nào cả

Deno Deploy được xây dựng trên các V8 isolate để xử lý logic edge nhanh, không phải để encode media tốn CPU. Không có subprocess API để spawn một binary native, cũng không có FFI để load nó, nên tiến trình ffmpeg không bao giờ khởi động được. Đây không phải một config flag hay một quyền mà bạn có thể cấp — những primitive mà ffmpeg cần đơn giản là không tồn tại trong isolate sandbox. Các bản WebAssembly của ffmpeg có tồn tại, nhưng chúng vượt xa giới hạn CPU và memory của isolate với bất kỳ video thực tế nào, và không thể stream một file lớn qua được.

  • Không có subprocess: Deno.Command và child_process không thể khởi chạy binary ffmpeg bên trong isolate.
  • Không có FFI: bạn không thể dlopen một thư viện ffmpeg native rồi gọi trực tiếp vào nó.
  • ffmpeg bản Wasm làm cạn kiệt CPU/memory của isolate với video thực tế và không thể stream input lớn.
  • Nền tảng này được tối ưu cho các request edge ngắn, không phải cho các tác vụ encode kéo dài nhiều giây.

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

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

OptionWhat it costs youVerdict
Bundle ffmpeg vào function Deno Deploy của bạnKhông có subprocess để khởi chạy binary ffmpeg
Tự host một container hoặc VMChi phí chạy 24/7 cộng thêm việc patch, scale và monitor
Chạy một job queue + workerHạ tầng mới: queue, worker, retry, xử lý dead-letter
Transcode ngay trong browser (WASM)Chậm, ngốn memory và crash trên mobile
Gọi Fotovid APIChỉ một request HTTPS; không cần chạy, đóng gói hay scale 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 key — không cần thẻ để bắt đầu. Bạn sẽ nhận được một key ID và secret, kết hợp lại thành Bearer token theo dạng p6_<key_id>:<secret>. Lưu nó vào một environment variable trên Deno Deploy để isolate của bạn xác thực được mà không cần ship bất kỳ binary nào.

  2. 2
    POST đến endpoint watermark

    Từ Deno handler của bạn, thực hiện một fetch bình thường để POST tới https://api.fotovid.co/v1/video/watermark kèm Bearer token của bạn. Gửi envelope tiêu chuẩn: một source_url trỏ đến HTTPS URL của video đầu vào, cùng một params object mô tả watermark — type (image, text, hoặc combo), watermark_image_url hoặc text, position như bottom-right, opacity, và scale. Fotovid sẽ pull source, chạy ffmpeg trên hạ tầng riêng của mình, và trả kết quả về trước khi isolate của bạn timeout.

  3. 3
    Dùng URL được trả về

    Response là flat JSON: một id, một type, và một url trỏ đến video đã hoàn tất, được host trên Fotovid, cùng với expires_at và duration. Bạn có thể đưa url đó thẳng cho client, hoặc fetch phía server và lưu bản sao của riêng bạn vào bucket mà bạn đang dùng. Hầu hết operation chỉ tốn 1 credit, nên một lệnh gọi watermark chỉ trừ 1 credit trong balance của bạn.

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.