Netlify Functions で ffmpeg:バンドルは無理でも、Fotovid がホスティングします。
Netlify Functions は AWS Lambda 上で動作するため、ffmpeg はバンドルサイズの上限を超え、デフォルトのタイムアウトにも引っかかってしまいます。処理は Fotovid に任せましょう。リクエストを1回送るだけで、どんなタイムアウトにも十分間に合う速さで結果 URL が返ってきます。
// netlify/functions/watermark.mts
export default async (req: Request) => {
const { videoUrl, logoUrl } = await req.json();
const res = await fetch("https://api.fotovid.co/v1/video/watermark", {
method: "POST",
headers: {
Authorization: `Bearer ${Netlify.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 });
};Netlify で ffmpeg が動かない理由
Netlify Functions は AWS Lambda 上で実行されますが、そこがまさに ffmpeg がつまずくポイントです。静的な ffmpeg バイナリは、zip 圧縮後 約50MB/展開後 250MB というバンドルサイズの上限に対して大きすぎるため、デプロイが失敗するか、バイナリがそのまま含まれずに終わります。仮に無理やり収めても、デフォルトの 10秒 という関数タイムアウトが実際のトランスコードを途中で強制終了させます。バックグラウンド関数を使っても 26秒 まで伸びるだけで、多くの動画処理にはそれでも足りません。「ローカルでは動くのに本番でタイムアウトする」という典型的な落とし穴です。
- ffmpeg バイナリと関連ライブラリが Lambda の展開後 250MB というバンドル上限を超える
- デフォルト 10秒(バックグラウンドで 26秒)のタイムアウトが実際のトランスコードを処理途中で終了させる
- コールドスタートやレイヤー管理の手間がレイテンシとパッケージングの負担を増やす
- ローカルでの成功がデプロイ後の関数では再現しない
Netlify で ffmpeg を動かすために試されてきた方法
Fotovid が登場する前は、これらが選択肢でした。どれも自分たちで抱え込みたくない作業です。
| Option | What it costs you | Verdict |
|---|---|---|
| ffmpeg を Netlify Function にバンドルする | 250MB のバンドル上限を超え、10秒の関数タイムアウトにも引っかかる | |
| コンテナや VM を自前でホスティングする | 常時稼働のコストに加え、パッチ適用・スケーリング・監視の手間がかかる | |
| ジョブキュー + ワーカーを構築する | キュー、ワーカー、リトライ、デッドレター処理という新規インフラが必要になる | |
| ブラウザ内でトランスコードする(WASM) | 処理が遅くメモリを大量に消費し、モバイルではクラッシュする | |
| Fotovid API を呼び出す | HTTPS リクエスト1回だけ。実行もパッケージングもスケーリングも不要 |
最初の呼び出しまで3ステップ
- 1無料の API キーを取得する
サインアップしてキーを作成します。認証には Authorization: Bearer p6_<key_id>:<secret> ヘッダーを使うだけで、バイナリも Lambda レイヤーも、Netlify Function にバンドルするものは何もありません。
- 2動画をウォーターマークエンドポイントに POST する
Netlify Function 内から、https://api.fotovid.co の POST /v1/video/watermark を呼び出します。標準のエンベロープとして、入力動画を指す source_url と params オブジェクトを送ります。type には image、text、combo のいずれかを指定し、位置は bottom-right のように指定し、さらに opacity、scale、padding を設定します。ffmpeg の処理は Fotovid 側で行われるため、あなたの関数はバンドルできないバイナリを呼び出す代わりに、高速な HTTPS リクエストを1回送るだけで済みます。
- 3ホスティングされた結果 URL を使う
レスポンスは id、type、url、expires_at を含むフラットな JSON です。url は Fotovid がホスティングする完成済み動画を指しています。クライアントにそのまま返すか、自前で保存してください。結果は一時的にホスティングされるものなので、ダウンロードして自分のアセット保管先に保存し直すことをおすすめします。
