统一视频接口
curl --request POST \
--url 'https://api.example.com/{{llmApiOrigin}}/v1/video/generations' \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": [
{}
],
"size": "<string>",
"duration": 123,
"seconds": {},
"metadata": {}
}
'import requests
url = "https://api.example.com/{{llmApiOrigin}}/v1/video/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": [{}],
"size": "<string>",
"duration": 123,
"seconds": {},
"metadata": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
prompt: '<string>',
image: '<string>',
images: [{}],
size: '<string>',
duration: 123,
seconds: {},
metadata: {}
})
};
fetch('https://api.example.com/{{llmApiOrigin}}/v1/video/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/{{llmApiOrigin}}/v1/video/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'prompt' => '<string>',
'image' => '<string>',
'images' => [
[
]
],
'size' => '<string>',
'duration' => 123,
'seconds' => [
],
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/{{llmApiOrigin}}/v1/video/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n {}\n ],\n \"size\": \"<string>\",\n \"duration\": 123,\n \"seconds\": {},\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/{{llmApiOrigin}}/v1/video/generations")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n {}\n ],\n \"size\": \"<string>\",\n \"duration\": 123,\n \"seconds\": {},\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/{{llmApiOrigin}}/v1/video/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n {}\n ],\n \"size\": \"<string>\",\n \"duration\": 123,\n \"seconds\": {},\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body视频系列
统一视频接口
统一视频生成接口(提交任务与查询任务)
POST
{llmApiOrigin}
/
v1
/
video
/
generations
统一视频接口
curl --request POST \
--url 'https://api.example.com/{{llmApiOrigin}}/v1/video/generations' \
--header 'Authorization: <authorization>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": [
{}
],
"size": "<string>",
"duration": 123,
"seconds": {},
"metadata": {}
}
'import requests
url = "https://api.example.com/{{llmApiOrigin}}/v1/video/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"image": "<string>",
"images": [{}],
"size": "<string>",
"duration": 123,
"seconds": {},
"metadata": {}
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
prompt: '<string>',
image: '<string>',
images: [{}],
size: '<string>',
duration: 123,
seconds: {},
metadata: {}
})
};
fetch('https://api.example.com/{{llmApiOrigin}}/v1/video/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/{{llmApiOrigin}}/v1/video/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'prompt' => '<string>',
'image' => '<string>',
'images' => [
[
]
],
'size' => '<string>',
'duration' => 123,
'seconds' => [
],
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/{{llmApiOrigin}}/v1/video/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n {}\n ],\n \"size\": \"<string>\",\n \"duration\": 123,\n \"seconds\": {},\n \"metadata\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/{{llmApiOrigin}}/v1/video/generations")
.header("Authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n {}\n ],\n \"size\": \"<string>\",\n \"duration\": 123,\n \"seconds\": {},\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/{{llmApiOrigin}}/v1/video/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"image\": \"<string>\",\n \"images\": [\n {}\n ],\n \"size\": \"<string>\",\n \"duration\": 123,\n \"seconds\": {},\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body简介
统一视频接口是 yunzhuai 提供的多模型视频生成入口,通过POST /v1/video/generations 提交任务、GET /v1/video/generations/{task_id} 查询状态。Sora 2、Veo、阿里万相、豆包 Seedance 1.x 等模型都可以通过此入口调用。
重要提示:视频生成是异步任务,提交后需要轮询查询接口直到状态变为 succeeded 或 failed。
更推荐按模型协议族选择入口(如 Seedance 2.0 走Seedance 官方接口),详见 视频生成总览。
认证
string
必填
Bearer Token,如
Bearer sk-xxxxxxxxxx提交视频任务
POSThttps://api.gzyzhuai.com/v1/video/generations
请求参数
string
必填
模型标识,支持的模型及功能如下:Sora 2 系列:
sora-2 - 文生视频、图生视频、视频生视频(Remix)
谷歌 Veo 系列:veo-3.0-fast-generate-001、veo-3.0-generate-preview、veo-3.1-fast-generate-preview、veo-3.1-generate-preview
阿里万相系列:wan2.5-t2v-preview(文生)、wan2.5-i2v-preview(图生,首帧)
豆包 Seedance 系列:doubao-seedance-1-0-lite-t2v-250428、doubao-seedance-1-0-lite-i2v-250428、doubao-seedance-1-0-pro-250528、doubao-seedance-1-5-pro-251215、doubao-seedance-1-5-pro-251215-noAudiostring
视频生成提示词。注意:豆包 Seedance 系列模型不需要此字段,提示词直接写在
metadata.content 数组的 text 字段中string
图生视频时的参考图片(支持 URL 或 Base64)
array
多张参考图片(URL 或 Base64 数组),部分模型用于首尾帧/多参考图场景
string
视频尺寸,不同模型格式不同(如
720x1280、1280x720、1920*1080)integer
默认值:"5"
视频时长(秒),不同模型支持范围不同
string|integer
视频时长(秒)的另一种写法,Sora 2 使用(如
"4"、"8")object
渠道/模型透传参数(如参考图列表、负向提示词、外部任务 ID 等),部分模型通过
metadata.content 传入多媒体内容(见下方模型专用参数)模型专用参数
不同模型使用不同的专用参数,按模型系列分类说明:- Sora 2
- Veo
- 阿里万相
- 豆包 Seedance(1.x)
string|integer
默认值:"4"
视频时长(秒),支持:
4、8、12string
默认值:"720x1280"
视频分辨率,支持:
720x1280(竖屏)、1280x720(横屏)string
参考图片(URL 或 Base64),用于图生视频;也可以通过
multipart/form-data 上传,字段名同为 input_referenceinteger
默认值:"4"
时长(秒),支持:
4、6、8string
宽高比,如
16:9、9:16string
默认值:"1080p"
分辨率,支持:
720p、1080p(部分模型只支持其中一个)boolean
默认值:"false"
是否生成同步音频。快速版模型会忽略该参数并始终包含音频
string
首帧参考图(URL 或 Base64),用于首帧约束
string
尾帧参考图(仅
veo-3.1 系列支持)integer
随机种子,用于复现结果
integer
默认值:true
每次生成的视频数量
personGeneration、addWatermark、fps)请参考对应模型文档。integer
默认值:"duration|整数"
时长(秒),支持:
5、10string
视频尺寸(仅 t2v),格式
宽度*高度,如 1280*720string
默认值:"720p"
分辨率:
480p、720p、1080pboolean
默认值:"false"
智能提示词
boolean
默认值:"false"
生成与画面同步的音频
string
自定义音频 URL
integer
随机种子
array
必填
Seedance 1.x 系列使用
metadata.content 数组传输入内容,参数通过提示词中的特殊标记控制:--ratio:宽高比(16:9、9:16、1:1、4:3、3:4、adaptive)--dur或--duration:时长(秒)--rs或--resolution:分辨率(480p、720p、1080p)--fps:帧率--seed:随机种子--wm或--watermark:水印开关--cf或--camerafixed:固定镜头
metadata.content 数组元素:{
"type": "text",
"text": "提示词内容 --ratio 16:9 --dur 5 --rs 720p --wm false"
},
{
"type": "image_url",
"image_url": { "url": "data:image/png;base64,..." },
"role": "first_frame" // 可选:first_frame / last_frame / reference_image
}
metadata 还可以设置 return_last_frame、callback_url。提交示例
- Sora 2
- Veo
- 阿里万相
- 豆包 Seedance 1.x
文生视频图生视频(首帧)
curl -X POST "https://api.gzyzhuai.com/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "一只可爱的小猫在花园里玩耍,阳光明媚,画面温馨",
"seconds": "4",
"size": "720x1280"
}'
curl -X POST "https://api.gzyzhuai.com/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "sora-2",
"prompt": "小猫在花园里追逐蝴蝶",
"seconds": "4",
"size": "720x1280",
"input_reference": "data:image/png;base64,iVBORw0KGgoAAxxxx..."
}'
curl -X POST "https://api.gzyzhuai.com/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3.1-fast-generate-preview",
"prompt": "科幻城市鸟瞰图,黎明时分,阳光穿透云层",
"duration": 8,
"aspectRatio": "16:9",
"generateAudio": false
}'
文生视频
curl -X POST "https://api.gzyzhuai.com/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "wan2.5-t2v-preview",
"prompt": "一只小猫慢慢睁开眼睛,耳朵轻轻抖动,镜头慢慢推进",
"duration": 5,
"size": "1280*720",
"generate_audio": true
}'
文生视频(标记风格)图生视频(首尾帧)
curl -X POST "https://api.gzyzhuai.com/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-1-5-pro-251215",
"metadata": {
"content": [
{
"type": "text",
"text": "一只可爱的小猫在花园里追逐蝴蝶,春天的阳光洒在花朵上 --ratio 16:9 --dur 6 --rs 720p --wm false"
}
]
}
}'
curl -X POST "https://api.gzyzhuai.com/v1/video/generations" \
-H "Authorization: Bearer sk-xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-1-5-pro-251215",
"metadata": {
"content": [
{ "type": "text", "text": "从静态画面过渡到动态场景 --ratio 16:9 --dur 8 --rs 720p --wm false" },
{ "type": "image_url", "image_url": { "url": "data:image/png;base64,AAAA...." }, "role": "first_frame" },
{ "type": "image_url", "image_url": { "url": "data:image/png;base64,BBBB...." }, "role": "last_frame" }
]
}
}'
提交响应
提交成功会返回任务 ID 及初始状态(字段随渠道略有差异):{
"task_id": "video_69095b4ce0048190893a01510c0c98b0",
"status": "queued",
"format": "mp4"
}
查询视频任务
GET{{base_url}}/v1/video/generations/{task_id}
根据任务 ID 查询任务状态与结果。
string
必填
由提交任务接口返回的任务 ID
使用示例
curl -X GET "https://api.gzyzhuai.com/v1/video/generations/video_6901234567...." \
-H "Authorization: Bearer sk-xxxxxxxxxx"
任务状态
| 状态 | 说明 | 建议操作 |
|---|---|---|
queued | 已排队,等待处理 | 继续轮询 |
in_progress / processing | 正在处理 | 继续轮询 |
succeeded | 已成功 | 获取视频 URL 或视频内容 |
failed | 已失败 | 查看 fail_reason |
完成时的响应示例
{
"task_id": "video_69095b4ce0048190893a01510c0c98b0",
"status": "succeeded",
"format": "mp4",
"url": "https://example.com/video.mp4"
}
响应里会伴随task_id、status、format、url(成功时)等字段;不同渠道可能附带额外字段,请以status为准。
失败时响应示例
{
"task_id": "video_69095b4...",
"status": "failed",
"format": "mp4",
"error": {
"code": 400,
"message": "提示词包含不当内容"
}
}
轮询示例
建议每 5 秒轮询一次,成功或失败即停止:import requests, time
def poll_video_task(task_id, api_key, max_wait=600):
url = f"https://api.gzyzhuai.com/v1/video/generations/{task_id}"
headers = {"Authorization": f"Bearer {api_key}"}
start = time.time()
while time.time() - start < max_wait:
data = requests.get(url, headers=headers).json()
status = data.get("status")
if status in ("succeeded", "failed"):
return data
time.sleep(5)
raise TimeoutError("video task timeout")
相关接口
视频生成总览
异步流程、入口选择与状态对照
视频内容获取
通过
GET /v1/videos/{task_id}/content 获取视频文件本体