動画生成

画像のURLを送信すると、その画像から生成された短いMP4動画が返されます。テキストプロンプトを追加して動画の内容を指示することも、省略して画像そのものから生成することもできます。

生成はバックグラウンドで実行されます。ジョブを作成し、数秒ごとに状態を確認すると、完了時に動画のURLを受け取れます。ほとんどの動画は1〜4分で完成します。

クイックスタート

APIキーと、Image to Videoが有効なImgixソース上の画像が必要です。ソースはAPIキーと同じアカウントに属している必要があります。

1. ジョブを作成します。 必須フィールドはurlのみです。autoモデルは画像に最適な生成エンジンを選択します。

curl -X POST https://api.imgix.com/api/v1/generations/video \
  -H "Authorization: Bearer $IMGIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-domain.imgix.net/image.jpg",
    "model": "auto"
  }'

2. ジョブを確認します。 手順1のidを使用します。statusがreadyまたはerroredになるまで、5〜10秒ごとに繰り返します。

curl https://api.imgix.com/api/v1/generations/video/66523ecdc9e5a19840c20941 \
  -H "Authorization: Bearer $IMGIX_API_KEY"

3. 動画を使用します。 result.urlはMP4を直接配信します。動画ファイルと同じように使用できます:

<video src="https://your-domain.imgix.net/image.jpg?itv=ef22b73a53&variant=542db280" controls autoplay muted loop playsinline></video>

例

以下の各動画は、1枚の静止画像から、併記したリクエストによって生成されたものです。

モデルの選び方

まずはautoから始めてください。動画の内容を細かく指定し、より早く結果を得たい場合はVeoモデルを使用します。

モデルプロンプト長さ(秒)aspect_ratio省略時の形状完成までの目安
auto省略可能1〜30ソース画像と同じ3〜4分
klingai省略可能1〜30ソース画像と同じ2分半〜4分
veo3.1必須4、6、816:91〜2分
veo3.1-fast必須4、6、816:91〜1分半

目安の時間は、過去30日間の本番ジョブの中央値と90パーセンタイルです。autoとklingaiのごく一部のジョブは最大20分かかります。

対応していない長さは拒否されません

モデルが指定されたdurationをレンダリングできない場合でも、ジョブは別の長さで成功します。Veoモデルは8秒、autoとklingaiは5秒でレンダリングします。たとえば、"model": "veo3.1", "duration": 10は8秒の動画を生成します。長さを選ぶ前に上の表を確認してください。

リクエストパラメータ

POST /api/v1/generations/videoはJSONボディを受け付けます。

パラメータ型必須説明
urlStringYes生成元の画像。Image to Videoが有効なImgixソース上にある必要があります。JPEGとPNGはそのまま使用され、その他の形式は事前に変換されます。
modelStringNoauto、klingai、veo3.1、veo3.1-fastのいずれか。モデルの選び方を参照してください。
promptStringVeoモデルの場合動画で起こってほしいことを自然な言葉で記述します。何がどう動くか、カメラがどこへ向かうかなど。例: "the band starts playing, the drummer counts in and the guitarist steps forward"。
durationIntegerNo長さ(秒)。デフォルトは8です。各モデルがレンダリングできる値はモデルの選び方を参照してください。
aspect_ratioStringNo16:9(横長)または9:16(縦長)。省略した場合、Veoモデルは16:9でレンダリングし、その他のモデルはソース画像に合わせます。

同じリクエストを再送した場合でも、ジョブごとに新しい動画が生成されます。

ジョブのライフサイクル

ステータス意味対応
startedジョブが受け付けられました。POSTのレスポンスで返されるステータスです。確認を続けます。
preparing動画を生成中です。確認を続けます。
ready動画がresult.urlで利用可能です。確認をやめて動画を使用します。
errored生成に失敗しました。確認をやめます。再試行するには新しいジョブを作成します。

5〜10秒ごとに確認してください。20分経過したら待機をやめ、ジョブを失敗として扱います。ジョブレコードは作成後24時間保持され、その後GETは404を返します。

レスポンスリファレンス

両方のエンドポイントは同じ形式を返します。

属性型説明
data.idStringジョブID。GET /api/v1/generations/video/:job_idで使用します。
statusStringstarted、preparing、ready、erroredのいずれか。
created_atIntegerジョブが作成された時刻のUnixタイムスタンプ。
updated_atIntegerジョブが完了した時刻のUnixタイムスタンプ。statusがreadyまたはerroredの場合に存在します。
result.urlStringstatusがreadyの場合に存在します。動画のURLで、ソースのurlにitvとvariantが追加されたものです。
error.codeIntegerstatusがerroredの場合に存在します。500。
error.messageStringstatusがerroredの場合に存在します。failed to generateなどの短い説明。

エラー

リクエストエラーはHTTPステータスと、detailフィールドを含むJSONボディを返します。ジョブは作成されず、何も生成されません。

HTTP原因detailの例
400modelが認識されない値です。unknown model 'not-a-model'
400Veoモデルでpromptが欠落しているか空です。prompt is required for model 'veo3.1'
400Veoモデルでaspect_ratioが16:9または9:16ではありません。aspect_ratio '1:1' is not supported for model 'veo3.1'; supported: 16:9, 9:16
400urlが有効なImgixソース上にありません。Bad Request
401APIキーが欠落しているか無効です。invalid token
401urlのソースがAPIキーとは別のアカウントに属しています。Unauthorized
403ソースが無効化されているか、Image to Videoが有効になっていません。Forbidden
404GETのみ。ジョブIDが存在しないか、レコードの有効期限が切れています。Job not found
422ボディの形式が正しくありません。urlの欠落、フィールドの型の誤り、またはaspect_ratioが認識されない値です。detailはフィールドエラーのリストです。[{"type": "missing", "loc": ["body", "url"], "msg": "Field required", ...}]
500ジョブを作成できませんでした。リクエストを再試行してください。Internal Server Error

作成後に失敗したジョブはHTTPエラーを返しません。GETは200とstatus: "errored"を返します:

{
  "data": {
    "type": "job",
    "id": "3f98a9b2c4d5e6f7a8b9c0d1",
    "attributes": {
      "status": "errored",
      "created_at": 1792783178,
      "updated_at": 1792783410,
      "error": {
        "code": 500,
        "message": "failed to generate"
      }
    }
  }
}

完全な例

各例はジョブを作成し、完了を待って、動画のURLを出力します。環境変数IMGIX_API_KEYを設定し、画像URLをご自身のものに置き換えてください。

// Node.js 18 or later. Run: IMGIX_API_KEY=... node generate.mjs
const API = "https://api.imgix.com/api/v1/generations/video";
const headers = {
  Authorization: `Bearer ${process.env.IMGIX_API_KEY}`,
  "Content-Type": "application/json",
};
 
async function generateVideo(request) {
  const created = await fetch(API, {
    method: "POST",
    headers,
    body: JSON.stringify(request),
  });
  if (!created.ok) {
    throw new Error(`${created.status}: ${await created.text()}`);
  }
  const { id } = (await created.json()).data;
 
  const deadline = Date.now() + 20 * 60 * 1000;
  while (Date.now() < deadline) {
    await new Promise((resolve) => setTimeout(resolve, 5000));
    const job = await fetch(`${API}/${id}`, { headers });
    const { status, result, error } = (await job.json()).data.attributes;
    if (status === "ready") return result.url;
    if (status === "errored") throw new Error(error.message);
  }
  throw new Error(`job ${id} did not finish within 20 minutes`);
}
 
const videoUrl = await generateVideo({
  url: "https://your-domain.imgix.net/image.jpg",
  model: "auto",
});
console.log(videoUrl);