Deno Deployでのffmpeg

なぜffmpegはDeno Deployで動かないのか?subprocessがないので、APIを呼びましょう。

Deno DeployはコードをV8 isolate上で実行するため、subprocessもFFIもなく、ffmpegバイナリを起動できません。代わりにfetch()経由でFotovidを呼び出しましょう。エンコードは別の場所で実行され、結果はシンプルなhttpsリンクとして返ってきます。

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 });
});

isolateモデルではffmpegは一切動作しません

Deno Deployは高速なエッジロジック向けのV8 isolate上に構築されており、CPUを大量に使うメディアエンコード向けではありません。ネイティブバイナリを起動するsubprocess APIも、読み込むためのFFIも存在しないため、ffmpegプロセスはそもそも起動できません。これは設定フラグや付与できる権限の問題ではなく、ffmpegが必要とするプリミティブがisolateサンドボックスに存在しないという構造的な制約です。ffmpegのWebAssembly移植版も存在しますが、実際の動画を扱うとisolateのCPU・メモリ上限を大きく超えてしまい、大きなファイルをストリーム処理することもできません。

  • subprocessなし:isolate内ではDeno.Commandもchild_processもffmpegバイナリを起動できません。
  • FFIなし:ネイティブのffmpegライブラリをdlopenして直接呼び出すことはできません。
  • Wasm版ffmpegは実際の動画でisolateのCPU・メモリを使い果たし、大きな入力をストリーム処理できません。
  • このプラットフォームは短時間のエッジリクエスト向けに最適化されており、数秒に及ぶエンコードジョブ向けではありません。

Deno Deployでffmpegを動かそうとするチームの試み

Fotovid登場以前の選択肢は以下の通りです。どれも自分では抱えたくない作業ばかりです。

OptionWhat it costs youVerdict
Deno Deploy関数にffmpegをバンドルするffmpegバイナリを起動するためのsubprocessがない
コンテナやVMを自前でホストする常時稼働のコストに加え、パッチ適用・スケーリング・監視が必要
ジョブキュー+ワーカーを構築する新たなインフラが必要:キュー、ワーカー、リトライ、デッドレター処理
ブラウザ内でトランスコードする(WASM)遅くてメモリを大量消費し、モバイルではクラッシュする
Fotovid APIを呼び出すHTTPSリクエスト1回だけ。実行・パッケージ化・スケーリングは不要
How it works

最初の呼び出しまで、たったの3ステップ

  1. 1
    無料のAPIキーを取得する

    サインアップしてキーを作成しましょう。最初はクレジットカード不要です。取得したkey IDとsecretを組み合わせると、p6_<key_id>:<secret>という形式のBearerトークンになります。これをDeno Deployの環境変数に保存すれば、バイナリを一切配布することなくisolateから認証できます。

  2. 2
    ウォーターマークエンドポイントにPOSTする

    Denoのハンドラから、Bearerトークンを付けて通常のfetchでhttps://api.fotovid.co/v1/video/watermarkにPOSTします。送るのは標準のエンベロープです。入力動画のHTTPS URLを指すsource_urlと、ウォーターマークの内容を記述するparamsオブジェクトを含めます。paramsにはtype(image、text、combo)、watermark_image_urlまたはtext、position(bottom-rightなど)、opacity、scaleを指定します。Fotovidがソースを取得し、自社インフラ上でffmpegを実行し、あなたのisolateがタイムアウトする前に応答を返します。

  3. 3
    返ってきたURLを使う

    レスポンスはフラットなJSONで、id、type、完成した動画を指すFotovidホストのurl、さらにexpires_atとdurationが含まれます。このurlをそのままクライアントに渡すか、サーバー側で取得して既存のバケットに自分のコピーとして保存してください。ほとんどの操作は1 creditなので、ウォーターマークの呼び出しは残高から1 credit消費するだけです。

よくある質問

1回のAPI呼び出しでリリース

無料のキーを取得し、5分以内に最初の呼び出しを試せます。