0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

同じコードで Veo 3.1 / MiniMax H3 Normal / Gemini Omni 1.1 Flash を切り替える:料金表と送信前チェック

0
Last updated at Posted at 2026-11-10

W45-Qiita-03.png

BeatAPI では、3つの動画モデルを同じエンドポイント POST /v1/videos/tasks、同じ API キーで呼べます。

では、model の名前を変えるだけで動くのか。答えは「一部だけ」です。エンドポイントと状態確認の流れは共通ですが、尺・解像度・比率の許容値はモデルごとに違います。そのまま送ると 400 になるか、思っていたのと違う尺で課金されます。

この記事では、値が違う項目を表にまとめ、送る前に止めるチェック関数を書きます。

8秒あたりの料金

モデル 720p(H3 Normal は 768p) 1080p 4K
Veo 3.1 Lite(音声つき) $0.15 $0.25 $0.75
Veo 3.1 Fast(音声つき) $0.30 $0.40 $0.90
Gemini Omni 1.1 Flash $0.48 $0.72 $1.44
MiniMax H3 Normal 768p $0.16 $0.20 —

MiniMax H3 Normal には 480p($0.14)もあります。768p は 720p と同じ仕様ではないので、比べるときは表記どおりに扱ってください。

料金は 2026年11月5日時点の beatapi.io の表示価格です。まとめて生成する前に料金ページで再確認してください。

値が違う項目

公開 OpenAPI(openapi.json)のリクエスト定義から、テキスト・開始フレーム入力の場合をまとめました。

項目 veo-3.1 minimax-h3-normal gemini-omni-1.1-flash
duration 送らない(8秒固定) 5〜15秒、省略時 5 3〜10秒、省略時 5
resolution 720p / 1080p / 4k 480p / 768p / 1080p 720p / 1080p / 4k
aspect_ratio 16:9 / 9:16 / auto 16:9 / 9:16 / 1:1 / 4:3 / 3:4 / 21:9 16:9 / 9:16
品質の指定 quality: Quality / Fast / Lite(省略時 Quality) なし なし
images(開始・終了フレーム) 1〜2枚 1〜2枚 1〜2枚
参照画像 reference_images 1〜3枚(quality は Fast / Lite) reference_images 最大4枚 reference_images 1〜10枚
音声 付く 付く(オフにする指定なし) 付く(オフにする指定なし)

特に気をつけたいのは3つです。

  • Veo 3.1 に duration を付けると通らない:8秒固定で、余分なプロパティは受け付けません。
  • quality を省略すると Veo 3.1 は Quality になる:上の表の Lite / Fast の料金で見積もっているなら、quality を必ず明示します。
  • H3 Normal と Omni は duration を省略すると5秒:8秒で見積もっているなら明示します。

送信前チェック関数

前回の記事の validate を、この3モデル用に広げます。

// validate.ts
type Spec = {
  duration: { min: number; max: number; fixed?: boolean };
  resolutions: string[];
  aspects: string[];
  qualities?: string[];
  maxReferenceImages: number;
};

const SPECS: Record<string, Spec> = {
  "veo-3.1": {
    duration: { min: 8, max: 8, fixed: true },
    resolutions: ["720p", "1080p", "4k", "4K"],
    aspects: ["16:9", "9:16", "auto"],
    qualities: ["Quality", "Fast", "Lite"],
    maxReferenceImages: 3,
  },
  "minimax-h3-normal": {
    duration: { min: 5, max: 15 },
    resolutions: ["480p", "768p", "1080p"],
    aspects: ["16:9", "9:16", "1:1", "4:3", "3:4", "21:9"],
    maxReferenceImages: 4,
  },
  "gemini-omni-1.1-flash": {
    duration: { min: 3, max: 10 },
    resolutions: ["720p", "1080p", "4k", "4K"],
    aspects: ["16:9", "9:16"],
    maxReferenceImages: 10,
  },
};

export type VideoReq = {
  model: string;
  prompt: string;
  duration?: number;
  resolution?: string;
  aspect_ratio?: string;
  quality?: string;
  images?: string[];
  reference_images?: string[];
};

export function validate(req: VideoReq): string[] {
  const spec = SPECS[req.model];
  if (!spec) return [`unknown model: ${req.model}`];
  const errors: string[] = [];

  if (spec.duration.fixed) {
    if (req.duration !== undefined)
      errors.push(`${req.model} は尺が固定です。duration を送らないでください`);
  } else if (req.duration === undefined) {
    errors.push(`${req.model} は duration を省略すると既定値になります。秒数を明示してください`);
  } else if (!Number.isInteger(req.duration) || req.duration < spec.duration.min || req.duration > spec.duration.max) {
    errors.push(`${req.model} の duration は ${spec.duration.min}〜${spec.duration.max} 秒です`);
  }

  if (req.resolution && !spec.resolutions.includes(req.resolution))
    errors.push(`${req.model} は解像度 ${req.resolution} に対応していません(${spec.resolutions.join(" / ")})`);

  if (req.aspect_ratio && !spec.aspects.includes(req.aspect_ratio))
    errors.push(`${req.model} は比率 ${req.aspect_ratio} を受け付けません`);

  if (spec.qualities) {
    if (!req.quality) errors.push(`${req.model} は quality を明示してください(省略すると最上位の料金になります)`);
    else if (!spec.qualities.includes(req.quality)) errors.push(`${req.model} の quality は ${spec.qualities.join(" / ")} です`);
    if (req.reference_images?.length && req.quality === "Quality")
      errors.push(`${req.model} は reference_images と Quality を併用できません`);
  } else if (req.quality) {
    errors.push(`${req.model} に quality はありません`);
  }

  if (req.images?.length && req.reference_images?.length)
    errors.push("images(開始・終了フレーム)と reference_images は同時に使えません");
  if (req.images && req.images.length > 2) errors.push("images は2枚までです");
  if (req.reference_images && req.reference_images.length > spec.maxReferenceImages)
    errors.push(`${req.model} の reference_images は ${spec.maxReferenceImages} 枚までです`);

  return errors;
}

使い方はこうです。同じプロンプトを3モデルに送る前に、全部チェックします。

import { validate, type VideoReq } from "./validate";

const prompt = "A glass water bottle on a wooden table. Slow orbit, soft window light, no text overlay.";

const reqs: VideoReq[] = [
  { model: "veo-3.1", prompt, quality: "Lite", resolution: "720p", aspect_ratio: "16:9" },
  { model: "minimax-h3-normal", prompt, duration: 8, resolution: "768p", aspect_ratio: "16:9" },
  { model: "gemini-omni-1.1-flash", prompt, duration: 8, resolution: "720p", aspect_ratio: "16:9" },
  // わざと間違えた例
  { model: "veo-3.1", prompt, duration: 8, resolution: "768p" },
];

for (const r of reqs) {
  const errs = validate(r);
  console.log(r.model, errs.length ? errs : "OK");
}
// 最後の行は、尺固定・解像度・quality 未指定の3つのエラーになる

チェックを通ったものだけを、前回までの submit → waitForTask に渡します。

// validate.ts に追記
const base = "https://api.beatapi.io/v1";
const headers = {
  Authorization: `Bearer ${process.env.BEATAPI_API_KEY}`,
  "Content-Type": "application/json",
};

export async function submitChecked(req: VideoReq, key: string): Promise<string> {
  const errs = validate(req);
  if (errs.length) throw new Error(errs.join("\n"));
  const res = await fetch(`${base}/videos/tasks`, {
    method: "POST",
    headers: { ...headers, "Idempotency-Key": key },
    body: JSON.stringify(req),
  });
  if (!res.ok) throw new Error(`submit failed: ${res.status} ${await res.text()}`);
  const { data } = await res.json();
  return data.id; // まず保存する
}

自動で読み替えない理由

720p を 768p に、duration: 8 を「Veo なら削除」に、と自動で読み替える実装も考えられます。でも私はおすすめしません。

  • 解像度や尺が変わると料金が変わる(8秒で H3 Normal の 768p は USD 0.16、Omni の 720p は USD 0.48)
  • 出力の大きさや長さも変わり、後工程(編集・配信)の前提が崩れる

黙って置き換えるより、送る前にはっきりエラーにして、呼び出し側に選ばせる方が安全です。

比べるときは条件を固定する

3つのモデルを比べるなら、プロンプト・尺・比率は同じにして、解像度は各モデルの近い値(720p と 768p)にそろえます。品質や処理時間はモデルごとに違うので、自分の用途で1本ずつ測ってから使い分けを決めます。

この表は 2026年11月5日時点の公開定義です。モデルが更新されると許容値も変わることがあるので、SPECS は公開 OpenAPI から定期的に作り直してください。

出典・確認日

  • BeatAPI 公開 API ドキュメント(openapi.json の Veo31VideoRequest / MinimaxH3NormalVideoRequest / GeminiOmni11FlashVideoRequest):2026年11月5日確認
  • 料金:api.beatapi.io/v1/pricing と beatapi.io 料金ページ(8秒):2026年11月5日確認

モデルの仕様と料金:https://beatapi.io/pricing

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?