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.
| Option | What it costs you | Verdict |
|---|---|---|
| Bundle ffmpeg vào function Deno Deploy của bạn | Không có subprocess để khởi chạy binary ffmpeg | |
| Tự host một container hoặc VM | Chi phí chạy 24/7 cộng thêm việc patch, scale và monitor | |
| Chạy một job queue + worker | Hạ 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 API | Chỉ một request HTTPS; không cần chạy, đóng gói hay scale gì cả |
Lệnh gọi đầu tiên của bạn, chỉ trong ba bước
- 1Lấ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.
- 2POST đế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.
- 3Dù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.
