跳到內容

Seedance

Seedance 是字節跳動的影片生成系列,由火山引擎方舟渠道提供。RouteAPI 會把請求轉換成方舟的 /api/v3/contents/generations/tasks 呼叫,因此每個任務都和其他影片模型一樣走提交、輪詢、下載的流程——見建立任務與查詢任務。本頁說明 Seedance 適配器讀取哪些欄位、各模型的限制、如何讀取 Seedance 任務紀錄,以及費用如何計算。

影片生成是異步任務:提交後保存 task_id,每 10–15 秒輪詢一次,狀態變成 SUCCESS 後下載。4 秒 480p 的影片通常需要 1–5 分鐘;解析度越高、長度越長,耗時越久。

模型 ID方舟模型解析度長度說明
seedance-2.5doubao-seedance-2-5-260628480p / 720p / 1080p4–30 秒支援草稿預覽、參考/編輯/延伸模式與 mov 輸出
seedance-2.0doubao-seedance-2-0-260128480p / 720p / 1080p / 4k4–15 秒支援圖片、影片與音訊參考素材
seedance-2.0-fastdoubao-seedance-2-0-fast-260128480p / 720p4–15 秒更快、更便宜的 2.0 變體
seedance-2.0-minidoubao-seedance-2-0-mini-260615480p / 720p4–15 秒低成本的 2.0 變體

請送出 GET /v1/models 回傳的模型 ID。提供這些模型的渠道會把它映射到第二欄對應的方舟模型名,這也是適配器同時接受兩種命名的原因。你的帳戶能用哪些模型、單價是多少,以 RouteAPI 控制台為準。

解析度與長度兩欄是字節對各模型的規定範圍。RouteAPI 不驗證這些範圍:我們這邊唯一的長度檢查是「頂層 duration / seconds 必須落在 0–3600」這條通用規則(見限制與錯誤)。其餘全部由方舟執行——在 2.0 模型上請求 30 秒、使用不支援的解析度或參考素材數量超限,請求都會先提交,再由方舟拒絕,表現為 fail_to_fetch_task,附帶方舟的狀態碼與訊息。RouteAPI 也不會為缺少的 resolution 或 duration 補預設值,預設值由方舟決定;這種情況下費用估算按 1080p 與 5 秒計算,所以預扣金額只是估算,不是方舟的預設值。

Seedance 1.x(doubao-seedance-1-0-*、doubao-seedance-1-5-*)已下線。映射到 1.x 名稱的請求會在模型映射之後、預扣或送往上游之前被拒絕,回傳 400 與錯誤碼 model_not_supported。

外層欄位Seedance 適配器的處理
prompt作為結尾的 text 項目附加,除非 metadata.content 已含 text 項目,或 content 是 2.5 的 draft_task。每個請求都必須有
images / image每張圖產生一個不帶 role 的 image_url 內容項目。存在 metadata.content 時被忽略
ratio作為方舟的 ratio 送出
resolution作為方舟的 resolution 送出
duration作為方舟的 duration 送出;能解析為正整數的頂層 seconds 會覆蓋它
generate_audio作為 generate_audio 送出;明確的 false 也會轉發
metadata解析進強型別結構,其中的值優先於頂層同名字段

size、input_reference 與 mode 屬於通用外層,但 Seedance 適配器不讀取它們:請改用 resolution / ratio,以及 images 或 content。

metadata 的型別會在提交前驗證:型別錯誤(content 給成物件、image_url 給成純字串、duration: "abc")回傳 400 且不扣費,訊息以 unmarshal metadata failed 開頭。metadata 裡的數值與布林欄位也接受字串形式("duration": "6"、"watermark": "false");頂層的純量欄位必須使用各自的 JSON 型別。

以下欄位從請求主體頂層讀取,因此用與其他供應商相同的結構送出即可,不必包進 metadata:

欄位類型說明
ratiostring長寬比:16:9、4:3、1:1、3:4、9:16、21:9 或 adaptive
resolutionstring480p、720p、1080p 或 4k,視模型支援而定
durationinteger長度(秒)。0 視為「未設定」不會送出;需要明確轉發 0 時請改用 metadata
generate_audioboolean是否產生配樂;false 會被明確轉發
secondsstring長度的舊式字串形式;能解析為正整數時同時覆蓋 duration 與 metadata.duration。非數字值會被忽略
欄位類型說明
contentarray輸入素材,取代 images;見 metadata.content
ratio、resolution、duration、generate_audio與頂層相同優先於頂層值。正的頂層 seconds 仍優先於最終的 duration
seedinteger隨機種子;0 會以明確值轉發
framesinteger畫格數。設定後費用估算用它取代長度,方舟也用它取代長度
camera_fixedboolean保持鏡頭固定
watermarkboolean在輸出加上供應商端浮水印。字節文件說明預設為 false
return_last_frameboolean同時以圖片形式回傳最後一格畫格
service_tierstring供應商服務等級,例如 default。原樣傳遞
execution_expires_afterinteger任務到期秒數。字節文件給出的範圍是 3600–259200,預設 172800,由方舟執行
priorityinteger供應商端佇列優先順序,0–9,數值越大越先執行。方舟只在你自己的帳戶內排序任務
safety_identifierstring你的終端使用者識別碼,最長 64 個字元。轉發給方舟,由方舟驗證長度
draftbooleanSeedance 2.5 草稿預覽——見草稿預覽
output_formatstring輸出容器,原樣轉發。Seedance 2.5 接受 mp4(預設)或 mov
omni_reference_task_typestringSeedance 2.5 參考模式,原樣轉發:auto、reference、edit 或 extend

callback_url 不會被轉發,也不會送出 callback——請輪詢結果。tools 同樣會被丟棄;此 API 不提供上游網路搜尋。包含這兩者在內的不認識鍵不會報錯,只會被忽略。metadata.model 不會被讀取:請求主體的 model 始終是渠道的上游模型名。

content 是有序的輸入項目陣列。每個項目都有 type、對應的 payload 欄位,以及可選的 role:

typePayloadrole 取值
texttext—
image_urlimage_url.urlfirst_frame、last_frame、reference_image
video_urlvideo_url.urlreference_video
audio_urlaudio_url.urlreference_audio
draft_taskdraft_task.id—

RouteAPI 只驗證項目的結構(payload 型別錯誤回傳 400),不驗證 role 名稱;不認識的 role 會照樣轉發,由方舟決定是否拒絕。URL 可以是公開 http(s) 連結、圖片與音訊的 data: URI,或 asset://<asset_id> 參照——上傳素材以及參照真人圖片(必須來自已驗證的素材群組)的方法見素材。

轉換過程帶來的規則:

  • 若有 content,會原樣使用;頂層 images 會被忽略而不是合併。空的 content 陣列視為未提供,頂層 images 仍然生效。
  • 若 content 沒有 text 項目,頂層的 prompt 會附加為結尾的文字項目。唯一例外是 content 為 draft_task 的 2.5 請求:不會附加 prompt,但請求主體仍必須有 prompt。
  • 在提示詞中以序號指稱素材(「image 1」「video 1」),依 content 順序按類型分別計數。
  • 首幀、首尾幀與多模態參考是三種不同模式。除非你已確認模型接受該組合,否則不要混用。

下表參考素材限制由方舟執行,不是 RouteAPI 的驗證:超限請求會先提交,再由上游拒絕。

項目Seedance 2.52.0 系列
參考圖數量1–301–9
參考影片最多 10 段,總長 ≤30 秒最多 3 段,總長 ≤15 秒
參考音訊最多 10 段,總長 ≤30 秒最多 3 段,總長 ≤15 秒,且必須同時有圖片或影片
單張圖片小於 30MB,寬高 300–6000 像素同左
單段影片mp4 / mov,小於 200MB同左
單段音訊wav / mp3,小於 15MB同左

Seedance 2.x 拒絕含真實人臉的參考圖與參考影片。需要使用真人肖像時,先完成真人核驗,再用 asset:// 參照已核驗的素材——素材 說明了核驗工作階段、已核驗的素材群組以及請求規則。

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0-fast",
"prompt": "A paper boat drifting down a rain-soaked street, cinematic lighting",
"ratio": "16:9",
"resolution": "720p",
"duration": 5,
"generate_audio": false
}'

images 中的單張圖片會成為不帶 role 的圖片項目,Seedance 將其視為首幀:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "The camera slowly pushes in as the person looks up and smiles",
"images": ["https://cdn.example.com/first.jpg"],
"ratio": "adaptive",
"resolution": "720p",
"duration": 5
}'

要明確控制首/尾幀,請使用 content 並把提示詞寫在裡面:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "The bud slowly opens into a full bloom",
"metadata": {
"content": [
{ "type": "text", "text": "The bud slowly opens into a full bloom" },
{ "type": "image_url", "image_url": { "url": "https://cdn.example.com/bud.jpg" }, "role": "first_frame" },
{ "type": "image_url", "image_url": { "url": "https://cdn.example.com/flower.jpg" }, "role": "last_frame" }
],
"ratio": "adaptive",
"resolution": "720p",
"duration": 5
}
}'

參考圖片、影片與音訊用 reference_* 系列 role 混在同一個 content 陣列中。依類型編號,序號按 content 順序計算,並在提示詞中這樣引用:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.0",
"prompt": "The person in image 1 dances following the moves in video 1, with audio 1 as background music",
"metadata": {
"content": [
{ "type": "text", "text": "The person in image 1 dances following the moves in video 1, with audio 1 as background music" },
{ "type": "image_url", "image_url": { "url": "https://cdn.example.com/person.jpg" }, "role": "reference_image" },
{ "type": "video_url", "video_url": { "url": "https://cdn.example.com/dance.mp4" }, "role": "reference_video" },
{ "type": "audio_url", "audio_url": { "url": "https://cdn.example.com/bgm.mp3" }, "role": "reference_audio" }
],
"ratio": "16:9",
"resolution": "720p",
"duration": 10
}
}'

包含影片輸入的請求會按該模型的影片輸入價格計費——見計費。參考素材的數量、長度與格式由方舟執行,見 metadata.content 下的限制表。

Seedance 2.5 增加了模式選擇與容器選擇。兩者對所有 Seedance 模型都會原樣轉發,是否接受由方舟決定:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"prompt": "Continue the scene as the camera pulls back over the harbour",
"metadata": {
"omni_reference_task_type": "extend",
"output_format": "mov",
"content": [
{ "type": "text", "text": "Continue the scene as the camera pulls back over the harbour" },
{ "type": "video_url", "video_url": { "url": "https://cdn.example.com/scene.mp4" }, "role": "reference_video" }
],
"ratio": "16:9",
"duration": 8
}
}'

omni_reference_task_type 取 auto(預設)、reference、edit 或 extend。每種模式期望的輸入組合由字節的介面約定決定,RouteAPI 只負責轉發該值。

草稿是一種低成本的預覽。用它生成最終影片是第二個任務,單獨計費。

  1. 提交帶 "metadata": { "draft": true, ... } 的請求,等待 SUCCESS。
  2. 從任務紀錄讀取上游任務 ID:GET /v1/video/generations/{task_id} → data.data.id。
  3. 提交一個新任務,其 content 是單一 draft_task。

第一步:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"prompt": "An astronaut walks slowly on the moon",
"metadata": { "draft": true, "duration": 5, "ratio": "16:9" }
}'

第二步,等草稿任務變成 SUCCESS 後執行。data.data.id 是方舟任務 ID,不是外層的 data.task_id:

Terminal window
curl -s https://api.routeapi.ai/v1/video/generations/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV \
-H "Authorization: Bearer $ROUTEAPI_KEY" | jq -r .data.data.id

第三步:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedance-2.5",
"prompt": "x",
"metadata": {
"content": [ { "type": "draft_task", "draft_task": { "id": "cgt-xxxxxxxx" } } ],
"resolution": "1080p",
"duration": 5
}
}'

prompt 仍然必填;這種形式下它不會作為文字送出,因此任何非空佔位符都可以。未明確給 duration 的草稿續作會按模型自動長度上限(2.5 為 30 秒,2.0 為 15 秒)預扣,再按實際用量結算。

草稿 ID 歸方舟所有。字節文件說明有效期為 7 天;RouteAPI 不驗證,過期的草稿 ID 會由上游報錯。

Terminal window
curl https://api.routeapi.ai/v1/video/generations/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{
"code": "success",
"message": "",
"data": {
"id": 4512,
"created_at": 1792048450,
"updated_at": 1792048569,
"task_id": "task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV",
"platform": "54",
"user_id": 1024,
"group": "default",
"channel_id": 18,
"quota": 108900,
"action": "generate",
"status": "SUCCESS",
"progress": "100%",
"fail_reason": "",
"result_url": "https://ark-content.example/xxxx.mp4",
"submit_time": 1792048458,
"start_time": 1792048461,
"finish_time": 1792048569,
"properties": {
"input": "{\"model\":\"doubao-seedance-2-0-fast-260128\",\"content\":[{\"type\":\"text\",\"text\":\"An orange cat stretching on a windowsill at sunrise\"}],\"generate_audio\":false,\"resolution\":\"720p\",\"ratio\":\"16:9\",\"duration\":5}",
"origin_model_name": "seedance-2.0-fast",
"upstream_model_name": "doubao-seedance-2-0-fast-260128"
},
"data": {
"id": "cgt-20261023100444-9kz46",
"model": "doubao-seedance-2-0-fast-260128",
"status": "succeeded",
"content": { "video_url": "https://ark-content.example/xxxx.mp4" },
"seed": 8202,
"resolution": "720p",
"duration": 5,
"ratio": "16:9",
"framespersecond": 24,
"usage": { "completion_tokens": 108900, "total_tokens": 108900 },
"created_at": 1792048458,
"updated_at": 1792048569
}
}
}

外層欄位由 RouteAPI 產生,查詢任務 有完整說明。對 Seedance 來說主要看 data.status、data.progress、data.result_url、data.fail_reason 與 data.quota——quota 是目前已扣金額,任務成功後即為結算後的金額。data.properties.input 是 RouteAPI 實際送給方舟的 JSON 快照(超過 512 位元組的媒體 URL 會被替換為 [omitted, N bytes]),是確認請求是否真的按你要的檔位送出的最快方式。data.platform 是渠道類型:豆包影片渠道為 54,火山引擎渠道為 45。

data.data 是方舟回傳的任務原文,按原樣儲存,任務結束前可能不完整。如果渠道的上游透過閘道外層({"code": 200, "data": {...}})回傳,下列欄位會再深一層,位於 data.data.data——判斷是否結束要看 data.status,而不是某個欄位是否存在。值得讀取的欄位:

欄位含義
data.data.id方舟任務 ID,與外層 data.task_id 不同。2.5 草稿正式生成時用它
data.data.content.video_url方舟回傳的影片位址,與外層 data.result_url 相同
data.data.content.last_frame_url尾幀圖片。僅在開啟 return_last_frame 時存在;RouteAPI 只原樣儲存這段載荷,僅從中解析 content.video_url
data.data.duration / resolution / ratio / framespersecond / seed實際生成參數
data.data.usage.completion_tokens / total_tokens方舟計量的 token 數;total_tokens 是結算用量
data.data.error失敗時方舟的錯誤碼與訊息

方舟狀態對任務紀錄的映射如下;RouteAPI 不認識的狀態按「仍在執行」處理:

方舟 status任務紀錄狀態進度
pending、queuedQUEUED10%
processing、runningIN_PROGRESS50%
succeededSUCCESS100%
failed、expired、cancelledFAILURE100%
其他IN_PROGRESS30%

如果方舟回傳 succeeded 但還沒有 video_url,RouteAPI 會保持 IN_PROGRESS 繼續輪詢,而不是結算一個沒有結果的任務。任務 FAILURE 時,fail_reason 是方舟的錯誤訊息,缺失時回落為 task failed;沒有 error 物件的 expired 或 cancelled 任務分別回報 task expired 與 task cancelled。如果 RouteAPI 自己的任務逾時(預設 24 小時)先觸發,狀態同樣是 FAILURE 並帶平台文案,兩種情況都會退還預扣額度。

data.result_url 是方舟自己的位址,方舟會按自己的計畫讓它過期(字節文件提到的長度約為 24 小時)——請盡快下載。RouteAPI 的內容端點在呼叫時重新取用已儲存的位址,可以省去你自行追蹤即將過期的連結,但無法讓已過期的位址重新可用:

Terminal window
curl -L -o out.mp4 \
https://api.routeapi.ai/v1/videos/task_G2RdWGt4t1nck5fYqTjwREKJo8Ze4RAV/content \
-H "Authorization: Bearer $ROUTEAPI_KEY"

內容端點只提供呼叫者自己已成功的任務:未完成的任務回傳 400 並說明目前狀態,未知或他人的 task_id 回傳 404,向方舟取檔失敗回傳 502。它的錯誤使用 {"error": {"message": "...", "type": "..."}} 結構,沒有 code 欄位。如果開啟了 return_last_frame,data.data.content.last_frame_url 也依方舟的過期時間失效——請一併下載。

Seedance 模型按 token 計費,而不是按請求或按秒。控制台單價是某個解析度檔每百萬輸出 token 的價格;帶影片輸入的請求按該模型的影片輸入價格計費。

提交時,RouteAPI 根據請求的解析度與畫格數估算輸出 token:

frames = 24 × duration + 1 (frames replaces duration when metadata.frames is set)
tokens = pixels × frames / 1024
pixels = 480p: 864×496, 720p: 1280×720, 1080p: 1920×1080, 4k: 3840×2160

長度省略時預設 5 秒;content 為 draft_task 且未明確給長度時,預設到模型的自動長度上限(2.5 為 30 秒,2.0 為 15 秒)。解析度省略或無法辨識時按 1080p 估算。字節的「自動長度」(-1)在頂層會被 0–3600 驗證拒絕;以字串 "-1" 寫在 metadata 裡則會轉發,估算同樣按自動長度上限計算。估算值乘以模型倍率、分組倍率與影片輸入倍率後作為預扣金額。對於按倍率而非固定價格計費的模型,該估算值會與一般預扣金額比較,取較大者預扣。任務完成時的 token 結算只在模型設定了倍率時執行;模型沒有倍率時預扣金額即為最終扣費(如果一個模型既沒有倍率也沒有固定價格,除非你的帳戶允許未設定倍率的模型,否則請求會被拒絕)。

請求提交時預扣成功後
給了 duration估算 token 數 × 單價方舟 usage.total_tokens × 單價,差額補扣或退回
未給 duration估算按 5 秒同樣的結算
設定了 metadata.frames估算使用畫格數同樣的結算
draft_task 且無 duration估算按 30 秒 / 15 秒同樣的結算
設定了按任務固定價格固定價不變,不做 token 結算
SUCCESS 但沒有 usage—保持預扣金額
FAILURE、expired、cancelled—退回預扣額度
400不預扣不扣費

每 token 價格取決於輸出解析度檔、請求是否包含影片輸入,以及在價格表中定義了該維度的模型上是否產生音訊。模型價格表生效且算出的倍率不為 1.0 時,提交回應的 X-New-Api-Other-Ratios 標頭會以 video_input 項目回傳該倍率。內建備援價格表為 2.0 模型登記了 base(480p / 720p)、1080p 與 4k 檔,並為每檔登記影片輸入價格;快速版只有 base 檔,影片輸入倍率為 22/37。seedance-2.5 與 seedance-2.0-mini 沒有內建價格表,分檔價格來自控制台設定。渠道也可以用按你所請求模型 ID 設定的 VideoPrice 表覆蓋倍率。以控制台顯示的模型價格與分檔為準。

算例(價格皆為假設,真實價格以控制台為準)。假設 seedance-2.0-fast 在 720p 檔為 每百萬輸出 token $2,分組倍率為 1:

  1. 以 720p、duration: 5 提交。估算:1280 × 720 = 921,600 像素,24 × 5 + 1 = 121 格,921,600 × 121 / 1024 = 108,900 token,預扣 $0.2178。
  2. 方舟回報 usage.total_tokens: 105000,結算金額為 $0.21,退回 $0.0078。
  3. 如果同一請求包含 reference_video 項目,內建快速版價格表會給估算值與結算值都乘上 22/37 ≈ 0.5946 的影片輸入倍率:預扣約 $0.1295,結算約 $0.1249。

餘額或 Key 額度不足以覆蓋預扣金額的請求會在送往上游之前被拒絕:錢包不足回傳 403 insufficient_user_quota,Key 額度不足回傳 403 pre_consume_token_quota_failed。

狀態碼錯誤碼含義
400invalid_requestprompt 缺失或為空、JSON 格式錯誤,或 metadata 欄位型別錯誤
400invalid_seconds頂層 duration / seconds 或數值型 metadata.duration 為負或大於 3600
400model_not_supported請求映射到已下線的 Seedance 1.x 模型
400task_not_existtask_id 未知或屬於其他帳戶
403insufficient_user_quota、pre_consume_token_quota_failed錢包餘額或 Key 額度不足以覆蓋預扣金額
429—上游容量耗盡;訊息會被替換為 Upstream load is saturated, please try again later
500build_request_failed、do_request_failed、invalid_response轉換失敗、上游不可達,或方舟沒有回傳任務 ID
500get_channel_failed轉送階段選擇渠道失敗(例如請求過程中渠道紀錄被刪除)
503get_channel_failed渠道在上游遇到憑證或計費硬故障,細節被隱藏
上游狀態碼fail_to_fetch_task方舟拒絕了提交;HTTP 狀態碼與訊息即方舟的

常見的 400 訊息,與實際回傳一致:

message原因
prompt is requiredprompt 缺失、為空或只有空白
seconds must be between 1 and 3600頂層 duration / seconds 或數值型 metadata.duration 為負或過大
unmarshal metadata failed: ...metadata 欄位型別錯誤,訊息後半段會指出具體欄位
model <id> is not supported by this channel原始或上游模型名匹配已下線的 Seedance 1.x 模型
task_not_exist任務 ID 未知或屬於其他帳戶

提交之後發生的失敗(內容審核、供應商逾時、取消)不會表現為 HTTP 錯誤。它們會以 FAILURE 連同 fail_reason 出現在任務紀錄中,預扣金額會被退回。expired 與 cancelled 也按同樣方式回報。

  • 介面位址不同。RouteAPI 不提供 /api/v3/contents/generations/tasks,把火山 SDK 的 Base URL 指過來無法使用。
  • 方舟專有參數放在 metadata 裡;通用欄位(prompt、images、ratio、resolution、duration、generate_audio)也可以寫在頂層,由 RouteAPI 映射。
  • 回傳的 task_id 是 RouteAPI 的 ID,不是方舟的。方舟的 ID 在任務紀錄的 data.data.id。
  • 你送出的是目錄模型 ID,渠道負責映射到方舟模型名,因此你不需要直接使用方舟的 endpoint ID(ep-...)。
  • 不支援任務列表、取消任務、回呼通知與網路搜尋;callback_url 與 tools 會被丟棄。
  • 計費按控制台價格表以 token 結算,不採用方舟自身的計費方式。

需要 bash、curl 與 jq。

#!/usr/bin/env bash
set -euo pipefail
: "${ROUTEAPI_KEY:?set ROUTEAPI_KEY first}"
BASE="${ROUTEAPI_BASE:-https://api.routeapi.ai}"
AUTH="Authorization: Bearer $ROUTEAPI_KEY"
TASK_ID=$(curl -sS -X POST "$BASE/v1/video/generations" \
-H "$AUTH" -H "Content-Type: application/json" \
-d '{"model":"seedance-2.0-fast","prompt":"An orange cat stretching on a windowsill at sunrise","duration":5,"resolution":"720p","ratio":"16:9","generate_audio":false}' \
| jq -er .task_id)
echo "task: $TASK_ID"
for _ in $(seq 1 60); do
RESP=$(curl -sS "$BASE/v1/video/generations/$TASK_ID" -H "$AUTH")
STATUS=$(printf '%s' "$RESP" | jq -r .data.status)
echo "status: $STATUS $(printf '%s' "$RESP" | jq -r .data.progress)"
case "$STATUS" in
SUCCESS)
curl -sSL -o "$TASK_ID.mp4" "$BASE/v1/videos/$TASK_ID/content" -H "$AUTH"
echo "saved: $TASK_ID.mp4"
exit 0
;;
FAILURE)
echo "failed: $(printf '%s' "$RESP" | jq -r .data.fail_reason)"
exit 1
;;
esac
sleep 15
done
echo "timed out waiting for the task"
exit 1

迴圈等待 15 分鐘;長任務或高解析度任務可以調大次數。