Cloudflare Workers で ffmpeg を使う

Cloudflare Workers で ffmpeg を動かすなら、バンドルせずに呼び出しましょう。

Workers は V8 isolate 上で動作するため、ファイルシステムもネイティブバイナリもなく、CPU 時間にも厳しい制限があります。Worker は Fotovid に URL を HTTPS で渡すだけ。エンコード処理は isolate の外側で実行され、結果はホスト済みリンクとして返ってくるので、CPU 予算を一切消費しません。

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

Worker が ffmpeg で詰まる理由

Cloudflare Workers はコンテナ上ではなく、V8 isolate の中で動作します。一時ファイルを書き込むファイルシステムはなく、ネイティブバイナリをシェルアウトして実行する手段もなく、リクエストごとの CPU 時間にも厳格な制限があります。ffmpeg バイナリはそもそもそこに存在できません。WASM 版は技術的にはロードできますが、isolate のメモリと CPU の予算に抑え込まれ、ちょっとしたクリップを超えると処理が止まってしまいます。現実的な選択肢はホスト型 API だけです。

  • ファイルシステムなし: ffmpeg は入力の読み込みと出力の書き込みに一時ファイルが必要ですが、Workers にはそれがありません。
  • ネイティブバイナリなし: V8 isolate 内では ffmpeg バイナリをインストールも実行もできません。
  • WASM 版の ffmpeg はロードできても isolate のメモリと CPU の上限に阻まれ、実際の動画では処理が止まるかタイムアウトします。
  • リクエストごとの厳しい CPU 予算により、トランスコード規模の処理はそもそも成立しません。

Cloudflare Workers で ffmpeg を動かそうとする際のよくある手段

Fotovid が登場する前は、これらが選択肢でした — どれも本来自分で抱えたくない作業です。

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

3ステップで最初の呼び出しを試す

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

    サインアップしてキーを作成します。取得できる Authorization: Bearer p6_<key_id>:<secret> トークンで、https://api.fotovid.co へのすべての呼び出しを認証できます。インフラ構築も ffmpeg のビルドも不要で、必要なのはヘッダーだけです。

  2. 2
    Worker から動画を POST する

    標準のエンベロープで POST /v1/video/watermark を呼び出します。入力動画の HTTPS URL を指す source_url と、params オブジェクトを渡します。params では type に image、text、combo のいずれかを指定し、さらに position (例: bottom-right)、opacity、scale を設定します。Worker 内からの単純な fetch なので、isolate のリクエストモデルにそのまま収まります。

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

    Fotovid はフラットな JSON を返します: { id, type, url, expires_at, duration }。url は完成した透かし入り動画が置かれた Fotovid のホスティング先を指します。そのままクライアントに渡すか、永続的に保存したい場合は自分のバケットにコピーしてください。ホストされた結果は一時的なものです。

よくある質問

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

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