mcpField
V
vidu-video

vidu-video

github.com/calesthioクリエイティブ・メディア219102 回インストール15 週間前に更新
リポジトリ

vidu-video について

Vidu Open Platform APIを使った動画生成の連携を設計するスキルです。制作チーム向けに、エンドポイントとモデルの選択、参照素材や音声の設定、実行前のリクエスト確認を支援します。

主な機能

  1. 01生成モードに応じたエンドポイントとモデルの選択
  2. 02テキスト・画像・始点終点・参照動画モード
  3. 03名前付き被写体とマルチフレームのワークフロー
  4. 04エンドポイント別の音声制御
  5. 05ドライラン計画と承認チェックポイント

活用シーン

  1. 01テキストプロンプトから動画を生成
  2. 02開始画像から目標フレームへのアニメーション
  3. 03名前付き被写体による会話動画の作成
  4. 04送信前の動画リクエスト計画と確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/calesthio/generative-media-skills --skill vidu-video

インストール後、Claude Code で/vidu-videoを入力して読み込まれたか確認します。

同梱ファイルEVAL.md

詳細

Vidu video

このスキルは、Vidu Open Platform API を利用した本番用リクエストまたは統合の設計に使用します。デフォルトではドライランで計画します。オペレーターがプロバイダー、エンドポイント、モデル、入力、リクエストダイジェスト、最大料金、保存先、開示計画を正確に承認するまでは、有料の生成、非公開メディアのアップロード、タスクのキャンセル、結果のダウンロードを行わないでください。

このドキュメントは、2026-07-10 に一次公開ドキュメントと照合して確認済みです。モデル、価格、受け付けるフィールド、ポリシー、提供状況は変動するため、実行直前にリンク先のエンドポイントと料金ページを再確認してください。

サービスの種類を混同しない

  • Open Platform API: https://api.vidu.com、API キー、組織レベルの上限、非同期タスク、API クレジットを使用します。ここではこのサービスを扱います。
  • Vidu consumer product: https://www.vidu.com と、そのサブスクリプション/プランのクレジットを使用します。API にそのクレジット、機能、ウォーターマークの動作、規約が適用されると想定しないでください。
  • Vidu-S1 (Beta): HTTP セッション設定、AliRTC メディア、WebSocket 制御を使用する、独立した対話型デジタルヒューマン製品です。Q3/Q2 のクリップモデルではありません。公開ページには現在、「1 minute to 2 hours」という宣伝文句と、600 秒のセッション上限が併記されています。料金欄には別途、2 秒あたり S1 クレジット 3、クレジット単価 0.03125、6 秒ごとの控除、2 秒間隔での切り上げ、セッション作成に最低 45 クレジットが必要と記載されています。書面による確認なしに、クリップ API の $0.005 のクレジット単価を使ってこれらの記述を換算しないでください。
  • S1 ドキュメント内の不整合: 手順 3 では、ブラウザーがカスタムヘッダーを設定できないため、ブラウザーの WebSocket 認証は URL クエリに含めると説明されています。一方、ページの「Important Notes」では認証ヘッダーに含める必要があると記載されています。未解決の問題として扱ってください。実装前に Vidu に現在の通信方式を確認し、ベアラー URL をログ/分析/リファラーに決して含めないでください。また、サンプルだけから安全なブラウザー設計を推定しないでください。
  • 中国向けホスト: S1 ページでは、中国向けに api.vidu.cn、海外向けに api.vidu.com が文書化されています。ここで説明する通常のクリップ用エンドポイントは api.vidu.com を使用しますが、ホスト名から計算処理の実行場所を推定しないでください。

まずモードを選び、その後モデルを選ぶ

エンドポイントの仕様は、ファミリー名よりも優先されます。モデルが存在していても、すべてのモードに対応しているとは限りません。

ニーズエンドポイント現時点で本番利用に適した選択肢主な制限
プロンプトのみPOST /ent/v2/text2videoviduq3-turbo、viduq3-pro。Q2/Q1 は文書化された互換性要件がある場合のみQ3:1~16 秒、540p/720p/1080p。アスペクト比は 16:9、9:16、3:4、4:3、1:1
1 枚の開始画像をアニメーション化POST /ent/v2/img2videoQ3 pro-fast/turbo/pro、Q2 pro-fast/pro/turbo、Q1、Vidu 2.0画像は 1 枚のみ。URL またはデータ URL。PNG/JPEG/JPG/WebP。アスペクト比は厳密に 1:4~4:1。≤50 MB。POST 本文全体は ≤20 MB
開始と終了を正確に指定POST /ent/v2/start-end2videoQ3 turbo/pro、Q2 pro-fast/pro/turbo、Q1/classic、Vidu 2.0順序どおりの画像がちょうど 2 枚必要。画像のアスペクト比の比率は 0.8~1.25。Q3 は 1~16 秒。Q2 のエンドポイントでは 1~8 秒と記載
名前付きエンティティ/会話POST /ent/v2/reference2video の subjects 形式ページに記載された対応リストは Q3 turbo、Q3、Q2、Q1、Vidu 2.0画像/テキストの subject 項目は合計 ≤7。subject あたり画像 ≤3 枚。@name で参照。Q3 の長さは 3~16 秒
名前のない参照画像同じエンドポイントの images 形式Q3 mix/turbo/Q3、Q2 pro/Q2、Q1、Vidu 2.0通常は画像 1~7 枚。動画も指定する場合、Q2-pro は画像 1~4 枚
参照動画/編集同じエンドポイントの videos 形式viduq2-pro のみ8 秒の動画は最大 1 本、または 5 秒の動画は最大 2 本。MP4/AVI/MOV。各動画 ≤100 MB。デコード後の base64 は <20 MB
複数キーフレームの連続性POST /ent/v2/multiframeviduq2-pro、viduq2-turbo のみ順序付きキーフレーム。各セグメントは 2~7 秒。540p/720p/1080p。フレーム/セグメントの数え方と料金の説明が曖昧なため、現在のページを確認してください
現行モデルファミリーの対応表
  • Q3 pro: 品質重視のプロンプト/画像/開始・終了フレーム生成に対応し、24 fps、1~16 秒、540p/720p/1080p、オプションで音声・映像を直接出力できます。
  • Q3 turbo: プロンプト/画像/開始・終了フレーム生成および参照生成に対応する、より低価格で高速な Q3 の選択肢です。プロ版を選ぶ理由が仕様書にない限り、最初のモーションテストにはこちらを使用してください。
  • Q3 pro-fast: 画像から動画への変換のみを対象として文書化されており、720p/1080p、1~16 秒に対応します。「fast」という名前でも、すべての設定で turbo より安いとは限りません。
  • Q3 mix: images による参照から動画への変換のみを対象とし、720p/1080p に対応します。料金表では3~16秒、エンドポイントの説明では1~16秒となっています。Vidu がこの矛盾を解消するまでは、安全側の範囲である 3~16秒 を使用してください。現在、名前付きエンティティの subjects 形式とオフピークには対応していません。
  • Q3(修飾子なし): 音声の同期に対応する参照から動画への変換モデルです。参照エンドポイントで受け付けられる識別子は異なるため、Q3 pro に置き換えないでください。
  • Q2 pro: 実際の参照動画、動画の編集/置換、または Q2 マルチフレームが必要な場合に使用してください。Q2 turbo/pro-fast は、それぞれ文書化された画像/開始・終了フレーム/マルチフレームの用途に対応します。Q2 と Q3 のパラメーターに互換性はありません。
  • Q1/classic および Vidu 2.0: 固定またはより限定された長さ/解像度に対応する、古い互換性の選択肢です。公開ドキュメントにはサポート終了日は記載されていないため、「非推奨」ではなく「古い」と表現してください。

公開されている Model Map は、一部のエンドポイントページに追いついていません。たとえば、新しい Q3 の参照識別子がすべて列挙されているわけではありません。情報が競合する場合は、該当エンドポイントの受け付け可能な値の一覧、最新の Pricing page、モデルマップ/更新通知の順に確認してください。それでも競合が解消しない場合は、サインイン済みのコンソールまたは Vidu サポートで確認してください。

音声の仕様はエンドポイントとモデルによって異なります

  • Q3 の生成では、audio: true を指定すると、同期された音声や効果音の生成を要求します。参照の subjects 形式も audio_type(all、speech_only、sound-effect_only)およびサブジェクトごとの voice_id に対応します。
  • Q3 では bgm を使用しません。両方を設定してミックスされると考えないでください。Q3 の画像から動画への変換では、voice_id は効果がないと文書化されています。
  • デフォルト値はページや形式によって異なります。audio は明示的に設定してください。映像のモーションテストには false を、承認済みのセリフには名前付きサブジェクト、正確な引用文、audio_type を使用してください。
  • Q2 の音声の料金と利用可否は異なります。現在、料金ページでは、音声を有効にした Q2 の画像/参照タスクに15クレジットが加算されます。
  • Vidu のテキストから音声への変換、TTS、音声クローン、リップシンク、デジタルヒューマン API は、それぞれ独立した機能です。これらのフィールドを動画エンドポイントに送信しないでください。

モデルが使用できるリファレンスを構築する

エンドポイントの契約に関する事実:

  • 被写体画像は128×128以上、アスペクト比1:4~4:1で、PNG/JPEG/JPG/WebP形式である必要があります。名前付き被写体ごとに、最大3枚の画像を指定できます。
  • Q3 mixは名前付きエンティティに対応していません。一覧にあるモデルのうち、メディアリスト形式のリファレンス動画を受け付けるのはQ2-proのみです。
  • subjects[].name はプロンプト内で @name として指定します。auto_subjects は別個のインテリジェントエンティティライブラリのオプションです。どのライブラリ素材が選択されるか把握していない場合は、有効にしないでください。

本番環境でのヒューリスティックであり、プロバイダーによる保証ではありません:

  1. 人物や物体ごとに固有で一貫した名前を付け、服装、年齢、素材、照明に一貫性のある鮮明なビューを2~3枚用意します。アイデンティティのリファレンスに集合写真を使うのは避けてください。
  2. 動作より前に、アイデンティティと変更してはならない特徴を記述します:@Mara, red linen coat, short black bob; coat and face remain unchanged.
  3. 1つのショットについて、被写体 → 動作 → 環境 → カメラ → 照明 → 音声の順に記述します。カットが多すぎたり、複数の動作を同時に指定したりすると、アイデンティティのずれが大きくなります。
  4. 形状やポーズの開始点・終了点には開始/終了を、アイデンティティには被写体リファレンスを、意図的に演出したシーケンスにはマルチフレームを使います。適切な制御モードの代わりに、プロンプトの文章で済ませないでください。
  5. 固定シードを使い、540p/720p、短い再生時間でテストします。1080pや長いクリップに費用をかける前に、動きとアイデンティティを承認してください。シードは比較に役立ちますが、モデルの更新をまたいだビット単位の再現性を保証するものではありません。

リクエストを構築する前に入力を準備します:

  • 論理アセットID、承認済みの実際のバイト列のSHA-256、バイト数、検出されたメディアタイプ、該当する場合は寸法/再生時間、権利/同意の記録、承認済みのロケーターを含む正規の入力マニフェストを作成します。URLはロケーターにすぎません。URLをハッシュしても、Viduが取得するバイト列を証明したことにはなりません。変更可能またはハッシュを計算できないソースコンテンツは拒否してください。
  • ハッシュ計算やステージングのためにインテグレーションがユーザーURLを参照する場合、HTTPSのみを許可します。userinfo、フラグメント、ループバック/プライベート/リンクローカル/メタデータの宛先、DNSリバインディング、未承認のポートは拒否し、リダイレクト数に上限を設けて、各ホップを再検証し、時間とバイト数の上限を適用します。任意のユーザーURLを中継せず、承認済みの読み取り専用ステージングURLをViduに送信してください。
  • 署名付きソースURLの対象は1つのオブジェクトに限定し、有効期間は必要最小限にします。クエリ文字列をログや承認画面に表示しないでください。バケットプレフィックス、一覧表示権限、再利用可能な書き込み資格情報を公開しないでください。
  • 独立したImage Uploadフローは、作成リンク、PUT、完了の3段階からなる、影響の大きい書き込み操作です。現行のドキュメントでは画像の上限は10 MB未満とされており、生成ページにある50 MBのファイル上限や20 MBのリクエスト本文上限とは異なります。別途承認を取得し、アップロード前にバイト列を検証して、返されたETag/URIを記録してください。また、例にあるストレージヘッダーから、保持期間や削除SLAを推測しないでください。
完全な例1 — 名前付きの対話被写体

意図と制約: 雨の市場での6秒間の対話ショット中、1人の俳優とデザインされた物体1つを識別可能な状態に保ちます。プロンプトでエンティティを @name として指定するため subjects 形式を使い、低コストのアイデンティティテストにはQ3 Turbo、normalモード、720p、明示的な視聴覚制御を使います。これはスキーマの説明のみを目的としています。明示的な承認なしに実行しないでください。

{
  "model": "viduq3-turbo",
  "auto_subjects": false,
  "subjects": [
    {
      "name": "Mara",
      "images": [
        "https://assets.example.test/mara-front.jpg",
        "https://assets.example.test/mara-three-quarter.jpg"
      ],
      "voice_id": "APPROVED_VOICE_ID"
    },
    {
      "name": "OrchidDrone",
      "images": ["https://assets.example.test/orchid-drone.png"]
    }
  ],
  "prompt": "@Mara walks beside @OrchidDrone through a rainy market. Their designs remain unchanged. One continuous medium tracking shot. @Mara says: 'We leave before sunrise.' Rain and footsteps only after the line.",
  "duration": 6,
  "resolution": "720p",
  "aspect_ratio": "16:9",
  "audio": true,
  "audio_type": "all",
  "seed": 18427,
  "off_peak": false,
  "payload": "job-20260710-shot-014"
}

予想される見積もりと結果: 現在のnormalモードのQ3 Turboリファレンス料金では、6 × 10 = 60 APIクレジット、税別で$0.30です。承認済みの台詞と環境音を含む連続したトラッキングショットが期待できますが、アイデンティティや台詞の逐語的な再現は保証されません。

レビューと修正: 顔や物体のずれ、未承認の音声、台詞の変更、余分な音楽、カットがあれば却下してください。まず動作とカメラの指定を簡素化して、同じ短い設定で再テストします。ブリーフで雨音や足音が不要な場合に限り speech_only を使い、リクエストを変更するたびに新しいダイジェストを取得して承認を得てください。

完全な例 2 — 開始点と終了点を固定

意図と制約: クリア済みの紙の鳥のフレームから、背景とカメラを固定したまま、クリア済みの飛行中のフレームに変換します。両端の構図が重要なため、開始点/終了点モードが適切な制御方法です。Q3 Pro、5秒、1080p、無音、通常モードは、品質を重視した承認済みのバリエーションです。

{
  "model": "viduq3-pro",
  "images": [
    "https://assets.example.test/shot-08-start.png",
    "https://assets.example.test/shot-08-end.png"
  ],
  "prompt": "The paper bird unfolds into flight while the locked camera remains still; preserve the cream background and cobalt ink texture.",
  "duration": 5,
  "resolution": "1080p",
  "audio": false,
  "seed": 9081,
  "off_peak": false,
  "payload": "job-20260710-shot-008"
}

予想される見積もりと結果: 5 × 24 = 120 API クレジット、税抜きで $0.60 です。正確な幾何学的変形ではなく、指定した終了点に向かう補間が期待されます。

レビューと修正: 終了フレームへの急な切り替わり、トポロジーの破綻、カメラの動き、背景の再設計があれば却下します。長さを増やす前に、2つのソースフレームの互換性を高めてください。より安価な Q3 Turbo 720p の動作テストは有意義なバリエーションですが、新しいリクエストと承認が必要です。

完全な例 3 — 名前のない製品リファレンス

意図と制約: 3つのクリア済み製品ビューを使用して、5秒間の回転中も名前のないランプの一貫性を保ちます。名前付きの subjects はサポートされていないため、直接 images 形式を使用し、Q3 Mix を選択します。5秒は、文書化されている3~16秒の料金範囲と、エンドポイントのより広い説明にある1~16秒の範囲内です。

{
  "model": "viduq3-mix",
  "images": [
    "https://assets.example.test/product-front.png",
    "https://assets.example.test/product-side.png",
    "https://assets.example.test/product-detail.png"
  ],
  "prompt": "The same brass desk lamp rotates slowly on a dark walnut table, one continuous product shot, no redesign, no text or logos added.",
  "duration": 5,
  "resolution": "720p",
  "aspect_ratio": "16:9",
  "seed": 22109,
  "off_peak": false,
  "payload": "job-20260710-product-003"
}

予想される見積もりと結果: 5 × 24 = 120 API クレジット、税抜きで $0.60 です。Q3 Mix には記載されているオフピーク料金がありません。メディアリストのリクエストスキーマには現在 audio リクエストフィールドが記載されていませんが、モデルの説明には視聴覚出力について言及されています。フィールドを独自に追加したり、無音を約束したりせず、返されたストリームを確認し、音声の状態が重要な場合は Vidu に確認してください。

レビューと修正: 製品の再設計、テキストやロゴの追加、ディテールの欠落、複数ショットへの切り替え、予期しない音声があれば却下します。画像を増やす前に、リファレンスの一貫性やトリミングを改善してください。より低コストのバリエーションは、720p の Q3 Turbo リファレンスです。モデルを変更する場合は、新しい見積もり、ダイジェスト、承認が必要です。

料金と承認

API クレジットは現在、適用される税金を除き、1クレジットあたり $0.005 です。2025-11-03 に Vidu は、価値を変えずに数値上の単位を10倍にしました。調整前のクレジット例は無視してください。

選択したモデルの、生成秒あたりの現在の通常時/オフピーク料金:

モデル/モード540p720p1080p
Q3 pro プロンプト/画像/開始点-終了点9 / 5 クレジット20 / 1024 / 12
Q3 turbo プロンプト/画像/開始点-終了点7 / 411 / 613 / 7
Q3 pro-fast 画像—20 / 1025 / 13
Q3 mix リファレンス—24 / オフピークなし29 / オフピークなし
Q3 turbo リファレンス4 / 210 / 513 / 7
Q3 リファレンス7 / 412 / 615 / 7

例:Q3 turbo のテキストから動画への生成、5秒、720p、通常時の場合は、税抜きで 11 × 5 = 55 credits = $0.275 です。Q3 pro、5秒、1080p、通常時の場合は 24 × 5 = 120 credits = $0.60 です。

off_peak: true はより安価ですが、最大48時間かかる場合があります。未完了のタスクは自動的にキャンセルされ、返金されます。互換性には条件があります。リファレンスページによると、Q3 は音声ありでオフピークを利用できますが、Q2/Q1/Vidu 2.0 では音声を false にする必要があります。Q3 mix にはオフピーク料金がありません。承認前に該当する料金行を確認してください。

承認記録には以下を含める必要があります:

provider=Vidu Open Platform API
endpoint=/ent/v2/text2video
model=viduq3-turbo
mode=normal (off_peak=false)
duration=5s resolution=720p aspect=16:9 audio=false
input_manifest_sha256=<hash of canonical prompt/source-byte hashes, byte counts, media facts, and logical IDs; URLs are locators only>
request_sha256=<hash of canonical final JSON body>
execution_manifest_sha256=<hash binding method, URL, non-secret key ID, input/request hashes, pricing date, expected/max charge, call count, retries, and destination>
pricing_verified_on=<UTC date rechecked against pricing page/console>
expected=55 API credits / USD 0.275 before tax
max_authorized_credits=55
max_authorized_usd=<operator ceiling>
allowed_calls=1; retries=0; destination=<approved path/bucket>

入力マニフェストのダイジェストには、ロケーター文字列だけでなく、ソースバイトとメディア情報を含める必要があります。実行マニフェストのダイジェストが承認トークンになります。エンドポイント、API キーの識別情報、本文、ソース、価格、上限額、呼び出し回数、再試行ポリシー、送信先のいずれかを変更すると、承認は無効になります。

料金ページまたはコンソールの見積もりがいずれかの上限額を超える場合は、送信前に停止してください。許可された1回の作成リクエストで異なるクレジット請求が返された場合は、タスク ID と請求例外の状態を保存し、それ以上の生成/キャンセル呼び出しは行わず、領収書の内容を Vidu と照合してください。一般的な予算を、別のモデル、再試行、アップスケール、プロンプトの推奨(is_rec は現在10クレジットを追加します)、Q2 の音声追加料金への承認と解釈しないでください。

ドライラン優先の1回呼び出し例

この標準ライブラリのみを使った Python の例は、意図的に上記の55クレジットのリクエストに固定されています。デフォルトモードでは、正規のリクエストと承認エンベロープを出力し、ネットワーク呼び出しも状態の書き込みも行いません。承認前に、実際の秘密情報ではないキー ID、送信先、上限額、価格の確認日、新しいクライアントリクエスト ID を指定して、ドライランを再実行してください。実行には、正確な実行マニフェストのダイジェストが必要で、1回の POST の前にリクエスト本文のダイジェストを取得します。Vidu は冪等性キーを定めていないため、送信後に発生した例外はすべて UNKNOWN になります。スクリプトは再試行しません。複数のホストやプロセスから送信できる場合は、このローカルファイルを使った例ではなく、トランザクション対応のデータストアを使用してください。

import datetime, hashlib, json, os, pathlib, sys, urllib.error, urllib.request
from decimal import Decimal

MODE = os.getenv("VIDU_MODE", "dry-run")
client_id = os.getenv("VIDU_CLIENT_REQUEST_ID", "dryrun-example")
endpoint = "https://api.vidu.com/ent/v2/text2video"
key_id = os.getenv("VIDU_KEY_ID", "UNBOUND")
destination = os.getenv("VIDU_DESTINATION", "UNSET")
pricing_verified_on = os.getenv("VIDU_PRICING_VERIFIED_ON", "UNVERIFIED")
body = {
    "model": "viduq3-turbo",
    "prompt": "A cobalt paper bird unfolds and glides across a cream studio background, one locked medium shot, preserve its ink texture.",
    "duration": 5,
    "resolution": "720p",
    "aspect_ratio": "16:9",
    "audio": False,
    "seed": 18427,
    "off_peak": False,
    "payload": client_id,
}
wire = json.dumps(body, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
digest = hashlib.sha256(wire).hexdigest()
input_manifest = {"kind": "text-only", "prompt_sha256": hashlib.sha256(body["prompt"].encode("utf-8")).hexdigest()}
input_digest = hashlib.sha256(json.dumps(input_manifest, sort_keys=True, separators=(",", ":")).encode("utf-8")).hexdigest()
expected_credits = 55
expected_usd = Decimal("0.275")
max_authorized_credits = int(os.getenv("VIDU_MAX_CREDITS", str(expected_credits)))
max_authorized_usd = Decimal(os.getenv("VIDU_MAX_USD", str(expected_usd)))
approval_manifest = {
    "provider": "Vidu Open Platform API", "method": "POST", "url": endpoint,
    "key_id": key_id, "input_manifest_sha256": input_digest, "request_sha256": digest,
    "pricing_verified_on": pricing_verified_on, "expected_credits": expected_credits,
    "expected_usd_before_tax": str(expected_usd), "max_authorized_credits": max_authorized_credits,
    "max_authorized_usd": str(max_authorized_usd),
    "allowed_calls": 1, "retries": 0, "destination": destination,
}
approval_wire = json.dumps(approval_manifest, sort_keys=True, separators=(",", ":"), ensure_ascii=False).encode("utf-8")
approval_digest = hashlib.sha256(approval_wire).hexdigest()
print(json.dumps({"mode": MODE, "execution_manifest_sha256": approval_digest,
                  "approval_manifest": approval_manifest, "input_manifest": input_manifest,
                  "body": body}, indent=2, ensure_ascii=False))
if MODE == "dry-run":
    raise SystemExit(0)
if MODE != "execute":
    raise SystemExit("VIDU_MODE must be dry-run or execute")
if client_id == "dryrun-example":
    raise SystemExit("Set a fresh VIDU_CLIENT_REQUEST_ID")
if key_id == "UNBOUND" or destination == "UNSET":
    raise SystemExit("Bind the non-secret key ID and destination before approval")
try:
    verified_date = datetime.date.fromisoformat(pricing_verified_on)
except ValueError:
    raise SystemExit("Set VIDU_PRICING_VERIFIED_ON to an ISO date")
if verified_date != datetime.datetime.now(datetime.timezone.utc).date():
    raise SystemExit("Pricing must be revalidated on the UTC submission date")
if os.environ.get("VIDU_APPROVED_MANIFEST_SHA256") != approval_digest:
    raise SystemExit("Exact execution manifest was not approved")
if max_authorized_credits < expected_credits or max_authorized_usd < expected_usd:
    raise SystemExit("Approved ceiling is below expected cost")
api_key = os.environ.get("VIDU_API_KEY", "")
if not api_key:
    raise SystemExit("VIDU_API_KEY is required")

state_dir = pathlib.Path(os.getenv("VIDU_STATE_DIR", ".vidu-state")).resolve()
state_dir.mkdir(parents=True, exist_ok=True)
state_path = state_dir / f"{digest}.json"
def replace_state(value):
    temp = state_path.with_suffix(f".tmp-{os.getpid()}")
    with open(temp, "x", encoding="utf-8") as f:
        json.dump(value, f)
        f.flush(); os.fsync(f.fileno())
    os.replace(temp, state_path)
try:
    fd = os.open(state_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
except FileExistsError:
    raise SystemExit("Digest already claimed; refusing a duplicate POST")
with os.fdopen(fd, "w", encoding="utf-8") as f:
    json.dump({"state": "PREPARED", "request_sha256": digest,
               "execution_manifest_sha256": approval_digest, "client_request_id": client_id}, f)
    f.flush(); os.fsync(f.fileno())

req = urllib.request.Request(
    endpoint, data=wire, method="POST",
    headers={"Authorization": f"Token {api_key}", "Content-Type": "application/json"})
try:
    with urllib.request.urlopen(req, timeout=45) as resp:
        raw = resp.read(1024 * 1024 + 1)
        if len(raw) > 1024 * 1024:
            raise RuntimeError("response exceeds 1 MiB")
        if resp.status not in (200, 201):
            raise RuntimeError(f"unexpected HTTP {resp.status}")
        result = json.loads(raw)
        task_id = result.get("task_id")
        if not isinstance(task_id, str) or not task_id:
            raise RuntimeError("successful response lacks task_id")
        charged_credits = result.get("credits")
        if not isinstance(charged_credits, int) or isinstance(charged_credits, bool):
            raise RuntimeError("successful response lacks an integer credits receipt")
except Exception as exc:
    replace_state({"state": "UNKNOWN", "request_sha256": digest,
        "execution_manifest_sha256": approval_digest,
        "client_request_id": client_id, "error_type": type(exc).__name__})
    raise SystemExit("POST outcome is UNKNOWN; do not retry. Reconcile in Vidu console/support.") from exc
final_state = "SUBMITTED" if charged_credits == expected_credits and charged_credits <= max_authorized_credits else "SUBMITTED_BILLING_EXCEPTION"
replace_state({"state": final_state, "request_sha256": digest,
    "execution_manifest_sha256": approval_digest,
    "client_request_id": client_id, "task_id": task_id, "charged_credits": charged_credits})
print(json.dumps({"task_id": task_id, "state": final_state,
                  "next": f"GET /ent/v2/tasks/{task_id}/creations"}))
if final_state != "SUBMITTED":
    raise SystemExit("Task was created with a credit variance; do not submit or cancel anything else")

ローカルの payload はタスク上にエコーされますが、検索可能な Task List のフィルターとしては文書化されていません。作成結果が不明瞭な場合は、正確な送信時刻、モデル、プロンプト、長さ、解像度、キー、ローカルのクライアント ID をもとに、コンソールやタスク履歴を確認してください。必要に応じて Vidu サポートに問い合わせてください。元のリクエストが作成されていないと確認できるまで、またはオペレーターが重複のリスクと費用を明示的に承認するまでは、代わりのリクエストを送信しないでください。

非同期タスクを安全に運用する

  1. task_id、正規のリクエスト、ダイジェスト、API キー識別子(秘密情報ではありません)、想定上限額、作成レスポンスを永続化します。
  2. 上限を設けた指数バックオフとジッターを使って、GET /ent/v2/tasks/{id}/creations をポーリングします。状態は created、queueing、processing、success、failed です。クライアントのタイムアウトをタスクの失敗として扱わないでください。
  3. 公開されているデフォルトは、キーごとではなく組織ごとに同時実行タスク5件です。超過したタスクはおおむね作成順にキューに入り、負荷状況によってはサービスが最大数未満で実行されることがあります。429 はリクエスト頻度が高すぎる場合やシステムによるスロットリングも示すため、読み取りをバックオフしてください。送信が受け付けられるからといって、キューに大量のタスクを投入しないでください。
  4. 成功したタスクは、課金された credits と creations[].{id,url,cover_url} を返します。失敗したタスクは err_code を返すため、構造化エラーのトレース ID を保存してください。ポリシーによる失敗は、回避すべきプロンプトの問題ではありません。
  5. キャンセルは /ent/v2/tasks/{id}/cancel への重大な影響を伴う POST です。タスクがキャンセル不可の状態に達していると、失敗する場合があります。タスクごとの承認を得たうえで、{} が返っただけで課金が取り消されたと思い込まず、終端状態と返金を確認してください。

コールバックは任意です。Vidu はコールバックの配信に失敗すると3回再試行するため、ハンドラーは冪等でなければなりません。本文を受け入れる前に、X-HMAC-ALGORITHM=hmac-sha256、アクセスキー vidu、Date の鮮度、署名対象ヘッダーの正確な順序付きリストを検証してください。次のように再構成します。

METHOD + "\n" + URI_PATH + "\n" + RAW_QUERY + "\n" + "vidu" + "\n" + DATE + "\n"
+ each "HeaderName:HeaderValue\n" in X-HMAC-SIGNED-HEADERS order
signature = base64(HMAC-SHA256(callback TokenSecret, signing_string))

定時間比較を使用し、(access_key, nonce) の短期間有効なリプレイキャッシュを保持して、古い Date を拒否してください。生の本文のサイズに上限を設け、署名検証後にのみ解析し、既知のタスク ID とスキーマ上有効な状態遷移を要求してからイベントを受け入れてください。確認応答を返す前に、生イベントのハッシュと結果の状態を永続的に保存します。コールバックの配信は厳密に1回ではないため、復旧手段としてポーリングも続けてください。Vidu がアプリケーションの TokenSecret として指定しているコールバック用認証情報を使用してください。任意のベアラーキーが同じように使えると推測しないでください。

管理下への移管と検証

作成 URL とカバー URL の有効期間は24 時間のみと記載されています。成功したら、HTTPS、承認済みのホスト/リダイレクトポリシー、各ホップでのパブリック IP アドレスの解決、タイムアウト、バイト数の上限、ストリーミングハッシュを適用するダウンローダーを使用し、直ちに承認済みの保存先へコピーしてください。固定された保存先ルート配下に新しく作成した隔離ファイルへ書き込み、パストラバーサル、シンボリックリンク/再解析ポイントによるルート外へのアクセス、上書き、コンテンツタイプとバイトシグネチャの不一致を拒否してください。署名付きクエリ文字列は決してログに記録しないでください。

各クリップについて:

  • Vidu のタスク ID/作成 ID、最終リクエスト、消費クレジット、URL(伏せ字処理済み)、受領時刻、SHA-256、バイト数、出所/開示メタデータを保持してください。
  • 想定される動画コンテンツタイプを必須としたうえで、ffprobe を使用してコンテナ、コーデック、実際の幅/高さ、fps、長さ、音声ストリームの有無を検証してください。
  • メタデータの確認だけでなく、全編をデコードしてください。HTML/エラー本文、メディアの途切れ、長さ/解像度の想定外の差異、予期しない実行可能ファイル/アーカイブの内容を拒否してください。
  • すべてのフレーム範囲を確認し、人物の同一性のずれ、余分な手足/物体、安全でないテキスト/ロゴ、カット、ちらつき、開始/終了条件への適合をチェックしてください。音声については、発話内容の正確さ、不要な声や音楽の有無、聞き取りやすさを確認してください。
  • 不合格データは隔離してください。以前に承認されたアーティファクトを上書きしないでください。元の生成物は、編集版/アップスケール版とは別に保持してください。

権利、プライバシー、開示、未確認事項

  • すべての顔、声、商標、著作物、機密ファイル、個人データ項目について、文書化された権利と同意を取得してください。欺瞞的ななりすまし、同意のない親密なコンテンツ、嫌がらせ、詐欺、禁止コンテンツを作成しないでください。
  • API 利用規約では、運用者に対し、エンドユーザーへの通知、必要な同意の取得、個人データの最小化、人による確認、出力への過度な依存の回避、および人物関連の出力を重要な判断や法的判断に使用しないことを求めています。また、ディープシンセシスによる出力を見分ける表示の削除、改ざん、隠蔽、および人間が作成したものとして提示することも禁止しています。Vidu の出所表示/ディープシンセシス表示を保持し、適切な可視の開示を追加してください。
  • Vidu は、運用とポリシーの適用のために入力/出力を監視または確認する場合があると述べています。プライバシーポリシーはユーザーコンテンツを対象とし、サービスプロバイダーによる処理を認め、固定の保存期間ではなく目的に基づく保存期間を定めています。また、個人データがシンガポールのサーバーに保存/転送される場合があるとしています。これは、すべての生成処理が同地で行われることの証明ではありません。
  • 公開ドキュメントには、API 全般に適用される学習不使用の保証、すべての入力/出力に対する固定の削除 SLA、完全な処理リージョン一覧、出力の所有権の帰属、モデルの EOL 日、冪等性キーは記載されていません。公開されているのは同時実行タスク数の 5 件であり、すべてに適用される単一のリクエスト/分の数値はありません。規制対象、機密性、データ所在地、所有権、補償、DPA、削除、学習に関する要件は、アップロード前に署名済みの契約条件で解決してください。
  • Vidu の 2024 年の技術レポートは、当時の U-ViT/拡散モデルを用いた Vidu システムと、当初の 1080p/16 秒という主張について説明しています。これは Q3 より前の資料であるため、Q3 のアーキテクチャ、安全性、学習データ、ベンチマーク性能の根拠として使用しないでください。

やみくもに費用をかけずにトラブルシューティングする

症状確認事項安全な対応
401/403ヘッダーが正確に Authorization: Token … となっているか、キー/アカウントの権限認証を修正します。キーを決して出力しないでください
400 FieldInvalidエンドポイント固有のモデル、長さ、解像度、アスペクト比、本文のサイズそのエンドポイントの仕様に照らして再検証し、新しいダイジェストでドライランします
400 ModelUnavailable古い識別子または一時的な利用不可停止します。モデルを黙って差し替えないでください
429 QuotaExceeded組織の同時実行数(タスク5件)またはカスタムクォータキュー内/実行中の処理が終わるまで待ちます。必要に応じて上限の変更を申請します
429 TooManyRequests/SystemThrottlingポーリング/送信の頻度ジッターを加えて待機時間を延ばし、サーバーからの指示があればそれに従います
AuditSubmitIllegal / CreationPolicyViolation入力/出力のモデレーション停止して権利と安全性を確認します。審査を回避するために難読化しないでください
queueing が長時間続く同時実行数またはオフピークモードモードと経過時間を報告します。オフピークの処理可能期間は48時間です
成功したのにURLが機能しない24時間でリンクが期限切れになった、または安全でないリダイレクトタスク履歴を確認します。成果物を確保できていない場合はサポートに連絡します
音声が違う/音声がないQ3 の audio、参照先の audio_type、ボイスのマッピング。Q3 は bgm を無視しますスキーマを修正し、再見積もりを行い、次の生成の前に新たな承認を得ます

主な情報源

コメント