Supabase Edge Functionsでffmpegを使う

Supabase Edge Functionsのffmpeg処理を、HTTPS呼び出し1回にオフロード。

Edge FunctionsはDeno上で動くため、ffmpegバイナリをspawnするchild_processがありません。関数はそのまま残し、エンコードだけをHTTPS呼び出しにオフロードすれば、完成したファイルのURLが返ってきます。

// supabase/functions/watermark/index.ts
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, // a Supabase Storage signed URL works here
      params: { type: "image", watermark_image_url: logoUrl, position: "bottom-right" },
    }),
  });

  const { url } = await res.json();
  return Response.json({ url });
});

Edge Functionでffmpegが動かない理由

Supabase Edge FunctionsはDenoランタイム上で実行され、child_processやsubprocessのAPIが存在しません。つまりffmpegバイナリをバンドルしたとしても、それを起動する手段自体がないのです。さらにCPUと実行時間の上限は、軽量なリクエスト処理を想定したサイズであり、メディアエンコードに必要な数秒〜数分単位の継続処理には対応していません。Storageトリガーはファイルが届いた瞬間にジョブを*開始*するには最適な場所ですが、実際のトランスコードは本物のエンコーダーを実行できる場所で行う必要があります。

  • Denoにはchild_process/subprocessがなく、ffmpegバイナリをexecできません
  • CPUと実行時間の上限は軽量なロジック向けで、メディアエンコード向けではありません
  • Storageトリガーはジョブの起点としては理想的だが、実処理は別の場所で行う必要があります
  • 静的ビルドのffmpeg、WASM、レイヤーはいずれもサイズではなくランタイム自体の壁に突き当たります

Supabaseでffmpegを動かす方法とその代償

Fotovid以前は、これらの選択肢しかありませんでした。どれも自分たちで抱え込みたくない作業です。

OptionWhat it costs youVerdict
Supabase FunctionにffmpegをバンドルするDenoにはchild_processがなく、バイナリをspawnできません
コンテナやVMをセルフホストする常時稼働のコストに加え、パッチ適用・スケーリング・監視も必要
ジョブキュー + ワーカーを構築するキュー、ワーカー、リトライ、デッドレター処理という新規インフラが必要
ブラウザ内でトランスコードする(WASM)動作が遅く、メモリを大量消費し、モバイルではクラッシュします
Fotovid APIを呼び出すHTTPSリクエスト1回のみ。実行も、パッケージ化も、スケーリングも不要
How it works

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

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

    サインアップしてキーを作成します。Fotovidはcreditの従量課金制で、$1 = 100 credits、ほとんどの操作は1 creditで実行できます。まずは主力機能である透かし呼び出しを組み込み、費用をかける前にエンドツーエンドでテストできます。

  2. 2
    関数から透かしエンドポイントを呼び出す

    同じEdge Function内(あるいはアップロード時に発火したStorageトリガー内)から、Authorization: Bearer p6_<key_id>:<secret>ヘッダーを付けてhttps://api.fotovid.co/v1/video/watermarkにPOSTします。送信するのは標準的なエンベロープです。動画のHTTPS URLを指すsource_url(Supabase Storageの署名付きURLがそのまま使えます)に加え、オーバーレイを記述するparamsオブジェクト、例えばtype imageやwatermark_image_url、bottom-rightのようなposition、opacityやscaleを指定します。関数側はHTTPSリクエストを1回発行するだけで、ffmpegの処理はFotovidがプラットフォーム外で実行するため、DenoのCPUや時間の上限に触れることは一切ありません。

  3. 3
    ホストされた結果のURLを使う

    レスポンスはフラットなJSONで、id、type、そしてFotovidがホストする完成済みの動画を指すurlが返ります。そのurlを呼び出し元にそのまま返すか、ダウンロードしてSupabase Storageに自分で保存してください。ホストされたURLはexpires_atを持つ一時的なものとして扱い、長期保存が必要な場合はコピーを永続化してください。

よくある質問

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

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