文件

文件

影片生成

使用 Google Veo 3.1 系列將文字或圖片轉為影片。提供兩種 API 形式:等待片段就緒後才回傳的單次同步端點,以及供正式工作負載使用的提交與輪詢非同步端點組。

端點:POST /v1/video/generations(同步端點,以下先介紹),以及 POST /v1/videos + GET /v1/videos/{id}(非同步,建議用於正式環境)。依模型和影片長度而定,生成時間從 30 秒到數分鐘不等——使用同步端點時,請將用戶端逾時設定得寬裕一些(600s 是安全值)。

文字轉影片

傳入 prompt 並選擇模型。aspect_ratio 為選填。

import requests

resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "a cinematic dolly-in on a red origami crane unfolding, soft light",
        "aspect_ratio": "16:9",
    },
    timeout=600,  # video generation can take minutes
)
print(resp.json()["data"][0]["url"])

duration(秒數)用來在按秒計費的模型(Seedance 系列模型和 Wan 2.7)上設定片段長度。Veo 模型會忽略它;每個 Veo 片段都是 8 秒,按影片計費。

# The models billed per second take a clip length: here 5 seconds of
# Seedance 2. Leave "duration" out and these models make a 5-second clip.
resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "seedance-2",
        "prompt": "a paper crane unfolds into a flock of birds over a city at dawn",
        "duration": 5,
        "aspect_ratio": "16:9",
    },
    timeout=600,
)
print(resp.json()["data"][0]["url"])

圖片轉影片

加入 image_url,Veo 就會以它為起點製作動畫——預設會將靜態圖片作為影片的第一格。

# Image-to-video: animate a still image. The source image can be an
# https URL, or inline base64 — Kunavo hosts it for the model automatically.
resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "the crane gently lifts off the desk",
        "image_url": "https://your-cdn.com/source.png",
    },
    timeout=600,
)
print(resp.json()["data"][0]["url"])
image_url 接受 https:// URL 或內嵌的 data: Base64 URI。模型執行前,Kunavo 會自動解碼 Base64 並將其託管於 CDN。

第一格、最後一格與參考圖

image_mode 用來指定 Veo 如何使用圖片。傳入 image_urls(陣列)即可提供多張圖片。

  • frame(預設)— 一張圖片會作為第一格;兩張圖片則分別作為第一格和最後一格,Veo 會生成兩者之間的轉場。
  • reference — 最多可使用三張圖片作為風格和主體參考。這些圖片會引導生成效果,但不會作為影片畫格出現。
# First + last frame: pass two images and Veo fills in the motion.
resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "a smooth transition between the two poses",
        "image_urls": [
            "https://your-cdn.com/first.png",
            "https://your-cdn.com/last.png",
        ],
        "image_mode": "frame",
    },
    timeout=600,
)

上傳來源畫格

如果只有本機檔案,請透過 POST /v1/files 上傳一次,並重複使用傳回的永久 URL。

# No public URL? Upload the still first, then animate it.
with open("frame.png", "rb") as f:
    up = requests.post(
        "https://api.kunavo.com/v1/files",
        headers={"Authorization": f"Bearer {API_KEY}"},
        files={"file": f},
    ).json()

resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "slow push-in, volumetric light",
        "image_url": up["url"],
    },
    timeout=600,
)

參數

參數類型備註
model字串(必填)來自 /v1/models 的影片模型代稱。
prompt字串(必填)鏡頭畫面的文字描述。
image_urlstring圖片轉影片使用的單張來源圖片。接受 URL 或 data: URI。
image_urlsstring[]多張來源圖片(Veo)。優先於 image_url。
image_modestringVeo 可使用「frame」(預設,第一格/最後一格)或「reference」(風格參考圖)。
durationint按秒計費模型的片段長度(秒),省略時為 5:Seedance 2、Seedance 2 Fast 和 Seedance 2.0 Mini 支援 4–15,Seedance 2.5 支援 4–30,Wan 2.7 支援 2–15。超出模型範圍的長度會遭到拒絕,並傳回 400。Veo 會忽略此參數:每個 Veo 片段都是 8 秒。
aspect_ratiostring例如「16:9」、「9:16」、「1:1」。
resolutionstring模型提供不同等級時使用,例如「720p」、「1080p」。
inputobject緊急替代方案 — 請參閱下方的 Raw input。

原始輸入的替代方式

在按秒計費的模型上,input 會原樣傳送至上游,取代我們的轉接器原本會建立的輸入。Veo 模型會忽略它。

決定價格的欄位是例外:resolution 一律會以該模型的其中一個級距傳送(未提供此欄位或其值不是該模型的級距時,傳送預設級距),duration 必須是該模型範圍內的整數秒數(其他任何值都會遭到拒絕,並傳回 400;未提供此欄位時傳送 5)。設定了 input 時,不會讀取請求本身的 resolution 和 duration。

影片模型

識別碼(slug)提供者備註
veo-3GoogleVeo 3.1 Fast — 比 Quality 更快、更便宜,支援原生音訊。
veo-3-qualityGoogleVeo 3.1 Quality — 最高保真度。
veo-3-liteGoogleVeo 3.1 Lite — 適合預覽的經濟等級。
seedance-2-5ByteDanceSeedance 2.5 — 最長 30 秒的影片片段、多模態參考素材、按秒計費。
seedance-2ByteDanceSeedance 2 — 多鏡頭一致性、最高 1080p、按秒計費。
seedance-2-fastByteDanceSeedance 2 Fast — 經濟等級、最高 720p、按秒計費。
seedance-2-miniByteDanceSeedance 2.0 Mini — 最便宜的等級,僅支援 480p/720p,適合草稿與大量生成。
wan-2-7AlibabaWan 2.7 — 電影感文字轉影片、按秒計費。

請務必查看 /models,了解即時模型清單和各模型價格。

延遲與逾時

  • Kunavo 最多會輪詢上游任務 540 秒,之後傳回 504。
  • 快速等級(Veo 3.1 Fast/Lite):通常為 30–90 秒。
  • 高品質等級和較長片段:2–5 分鐘。
  • 請將 HTTP 用戶端逾時設為至少 600s。
  • 在網路不穩定或使用行動裝置的情況下,建議改用非同步 API——提交後幾秒內便會回傳,您可再輪詢取得結果。

非同步 API(提交 + 輪詢)

端點:POST /v1/videos + GET /v1/videos/{id}。這些端點回傳的任務物件使用 OpenAI 影片物件的欄位名稱和狀態值,並額外包含存放影片片段 URL 的 output 欄位。請求主體為包含上述參數的 JSON。

上方的同步端點會讓 HTTP 連線保持開啟最多九分鐘,適合單次執行的指令碼,但在行動裝置上不可靠,也會降低伺服器效率。非同步端點組會立即傳回 vid_* ID;您可輪詢 GET /v1/videos/{id},直到 status 為 completed 或 failed。模型、價格和封存 URL 都相同。

import requests, time

# 1. Submit — returns immediately with a task id. No long-lived connection.
submit = requests.post(
    "https://api.kunavo.com/v1/videos",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        # Optional: retrying with the same key inside ~24h returns the
        # original task rather than submitting again.
        "Idempotency-Key": "my-task-uuid",
    },
    json={
        "model": "veo-3",
        "prompt": "a cinematic dolly-in on a red origami crane",
        "aspect_ratio": "16:9",
    },
    timeout=60,
).json()

task_id = submit["id"]              # "vid_abc..."
status  = submit["status"]          # "queued"

# 2. Poll until terminal. Recommended cadence: 5s, backing off to 30s.
while status not in ("completed", "failed"):
    time.sleep(5)
    r = requests.get(
        f"https://api.kunavo.com/v1/videos/{task_id}",
        headers={"Authorization": f"Bearer {API_KEY}"},
        timeout=30,
    ).json()
    status = r["status"]

if status == "failed":
    raise RuntimeError(r["error"]["message"])
print(r["output"]["url"])

使用 OpenAI SDK 時,請如以下範例所示,透過 client.post 傳送該請求主體,並透過 client.get 輪詢。SDK 自有的 client.videos.create 在此無法運作:它只接受 Sora 的參數,且會以 multipart 表單傳送這些參數(Python SDK 2.27.0 版起),而此端點會以 400 拒絕該 multipart 請求。

import time
from openai import OpenAI

client = OpenAI(api_key=API_KEY, base_url="https://api.kunavo.com/v1")

# The same JSON body, sent with the client's own post().
task = client.post(
    "/videos",
    body={
        "model": "veo-3",
        "prompt": "a cinematic dolly-in on a red origami crane",
        "aspect_ratio": "16:9",
    },
    # object hands back the JSON as parsed. Passing dict instead raises
    # after the task has been created.
    cast_to=object,
    options={"headers": {"Idempotency-Key": "my-task-uuid"}},
)

while task["status"] not in ("completed", "failed"):
    time.sleep(5)
    task = client.get(f"/videos/{task['id']}", cast_to=object)

if task["status"] == "failed":
    raise RuntimeError(task["error"]["message"])
print(task["output"]["url"])

回應格式

欄位類型備註
idstring以 vid_ 為前綴的任務 ID。上游變更不會影響此 ID。
objectstring"video".
statusstringqueued | in_progress | completed | failed。
modelstring你提交的模型 slug。
created_atint我們接受提交時的 Unix 秒數。
completed_atint | null進入終止狀態時的 Unix 秒數——待處理時為 null。
expires_atint提交後滿 30 天時的 Unix 秒數:至少在此之前都可以輪詢該任務。其結果 URL 不會過期。
progressint0–100。目前在任務結束前會回報 0,結束時則回報 100。
outputobject | null完成時為 {url, urls[], duration_seconds, resolution}。duration_seconds 是向模型請求的片段長度,Veo 為 null;resolution 是片段的解析度級距,沒有記錄時為 null。
errorobject | null失敗時為 {code, message}。

標頭與慣例

  • Idempotency-Key(選填,最多 128 個字元)— 在同一帳戶中使用相同金鑰重複提交時,會傳回原有任務,不會建立重複任務。適用於重試迴圈。
  • POST /v1/videos 在首次提交時會傳回 202 Accepted;使用冪等金鑰重播先前結果時,則傳回 200 OK。
  • GET /v1/videos/{id} 僅限任務擁有者存取:若查詢屬於其他帳戶的任務,會傳回 404——我們絕不會確認其他人的任務 ID 是否存在。
  • 建議的輪詢間隔:5 秒,並使用指數退避,最長增至 30 秒。依模型和解析度而定,任務通常會在 30 秒至 5 分鐘內完成。

如何選擇

同步 /v1/video/generations非同步 /v1/videos
最適合一次性指令碼、Notebook正式環境、行動裝置、長時間執行的工作
網路連線最多保持開啟 9 分鐘幾秒內提交;按你的時間輪詢
失敗復原失去回應 = 失去任務在 expires_at 到期前,隨時重新查詢該 ID
並行數每次呼叫佔用一個伺服器工作程序提交後立即釋放連線
回應格式OpenAI /images/generations 格式OpenAI /videos 格式

回應與儲存

回應採用 OpenAI 標準格式 — data[].url。URL 是永久的 files.kunavo.com 連結:Kunavo 會將每個結果封存至自己的 CDN,因此不同於原始上游 URL,這些連結永不過期。每段影片也會顯示在 /app/assets。

接下來可以查看