跳转到主要内容
POST
/
v1
/
videos
图生视频:基于参考图生成视频任务
curl --request POST \
  --url https://api.apiyi.com/v1/videos \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: multipart/form-data' \
  --form model=veo-3.1-fast-generate-preview \
  --form 'prompt=镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音' \
  --form input_reference='@example-file'
{
  "id": "task_xxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "queued",
  "progress": 0,
  "created_at": 1775025000,
  "completed_at": 1775025090
}

Documentation Index

Fetch the complete documentation index at: https://docs.apiyi.com/llms.txt

Use this file to discover all available pages before exploring further.

右侧的交互式 Playground 支持直接在线调试。请在 Authorization 中填入你的 API Key(格式:Bearer sk-xxx),上传一张参考图、输入 prompt、选择 model / duration / resolution 后一键发送即可。默认分组 Default 即可调用,无需切换专属分组
场景说明:本页用于「基于参考图生成视频」——上传一张图片作为视频的视觉锚点 / 起始帧,让静态画面”动起来”。如果不需要参考图,请使用 文生视频接口(同一端点,JSON 请求体)。
⚠️ 图生视频专属约束
  • Content-Type 必须是 multipart/form-data(不是 JSON)
  • 仅支持 1 张参考图,字段名固定 input_reference,传多张只取第一张
  • 不接受远程 URL,必须是文件上传或 Base64
  • 接受格式:image/jpeg / image/png / image/webp
  • duration 仍然必须传字符串 "4" / "6" / "8",传数字会被拒
  • 1080p / 4k 时 duration 必须 "8"
Google 官方 Veo 3.1 有多参考图 / 首尾帧 / 视频扩展能力,本站官转通道暂未开放。首尾帧需求请用 VEO 3.1(官逆)-fl 系列模型。

代码示例

Python(OpenAI SDK 风格 · 推荐 client.post 底层调用)

{/* OpenAI 官方 SDK 没有 videos.create 方法,/v1/videos 是自定义路径,需用底层 client.post() */}
from openai import OpenAI
import time, mimetypes

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.apiyi.com/v1"
)

# 第 1 步:multipart 上传(OpenAI SDK 底层 client.post 自动处理 multipart 边界)
with open("./lighthouse.png", "rb") as f:
    resp = client.post(
        "/videos",
        body=None,
        files={
            "input_reference": ("lighthouse.png", f, "image/png")
        },
        extra_body={
            "model": "veo-3.1-fast-generate-preview",
            "prompt": "镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪声",
            "duration": "8",  # ⚠️ 必须字符串
            "size": "1280x720",
            "resolution": "720p",
            "aspectRatio": "16:9"
        },
        cast_to=dict
    )
task_id = resp["task_id"]
print(f"Task ID: {task_id}, status: {resp['status']}")

# 第 2 步:轮询(最长等 3 分钟)
deadline = time.time() + 180
while time.time() < deadline:
    status_resp = client.get(f"/videos/{task_id}", cast_to=dict)
    print(f"Status: {status_resp['status']}, progress: {status_resp.get('progress', 0)}%")
    if status_resp["status"] == "completed":
        break
    if status_resp["status"] == "failed":
        raise RuntimeError(f"Generation failed: {status_resp}")
    time.sleep(8)

# 第 3 步:下载(带重试兜底)
import urllib.request, urllib.error
time.sleep(4)
for i in range(5):
    try:
        req = urllib.request.Request(
            f"https://api.apiyi.com/v1/videos/{task_id}/content",
            headers={"Authorization": "Bearer sk-your-api-key"}
        )
        with urllib.request.urlopen(req, timeout=180) as r, open("output.mp4", "wb") as f:
            while chunk := r.read(1 << 16):
                f.write(chunk)
        break
    except urllib.error.HTTPError as e:
        if i == 4:
            raise
        time.sleep(4)
print("Saved: output.mp4")

Python(原生 requests + multipart)

import requests
import time

API_KEY = "sk-your-api-key"
BASE_URL = "https://api.apiyi.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}

# 第 1 步:multipart 上传参考图 + 表单字段
with open("./lighthouse.png", "rb") as f:
    resp = requests.post(
        f"{BASE_URL}/videos",
        headers=HEADERS,  # 不要手动加 Content-Type,requests 会自动处理 multipart 边界
        data={
            "model": "veo-3.1-fast-generate-preview",
            "prompt": "镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音",
            "duration": "8",  # ⚠️ 字符串,不是数字
            "size": "1280x720",
            "resolution": "720p",
            "aspectRatio": "16:9",
            "seed": "20260521"
        },
        files={
            "input_reference": ("lighthouse.png", f, "image/png")
        },
        timeout=60  # multipart 上传大图可能慢,超时建议 60 秒
    ).json()
task_id = resp["task_id"]
print(f"Task ID: {task_id}")

# 第 2 步:轮询
deadline = time.time() + 180
while time.time() < deadline:
    s = requests.get(f"{BASE_URL}/videos/{task_id}", headers=HEADERS).json()
    print(f"Status: {s['status']}, progress: {s.get('progress', 0)}%")
    if s["status"] == "completed":
        break
    if s["status"] == "failed":
        raise RuntimeError(s)
    time.sleep(8)

# 第 3 步:下载(带 3 次重试)
time.sleep(4)
for i in range(5):
    try:
        with requests.get(
            f"{BASE_URL}/videos/{task_id}/content",
            headers=HEADERS, stream=True, timeout=180
        ) as r:
            r.raise_for_status()
            with open("output.mp4", "wb") as f:
                for chunk in r.iter_content(chunk_size=8192):
                    f.write(chunk)
        break
    except requests.HTTPError:
        if i == 4:
            raise
        time.sleep(4)
print("Saved: output.mp4")

cURL(multipart 上传)

{/* 1 步:multipart 上传(注意 -F 字段顺序,input_reference @ 引用本地文件)*/}
RESP=$(curl -sS -X POST "https://api.apiyi.com/v1/videos" \
  -H "Authorization: Bearer sk-your-api-key" \
  -F "model=veo-3.1-fast-generate-preview" \
  -F "prompt=镜头从灯塔基座缓慢上升至塔顶,黄昏光线" \
  -F "duration=8" \
  -F "size=1280x720" \
  -F "resolution=720p" \
  -F "aspectRatio=16:9" \
  -F "input_reference=@./lighthouse.png;type=image/png")
TASK_ID=$(echo "$RESP" | python3 -c 'import sys,json;print(json.load(sys.stdin)["task_id"])')
echo "task_id=$TASK_ID"

{/* 2 步:轮询状态 */}
while :; do
  S=$(curl -sS -H "Authorization: Bearer sk-your-api-key" "https://api.apiyi.com/v1/videos/$TASK_ID")
  ST=$(echo "$S" | python3 -c 'import sys,json;print(json.load(sys.stdin)["status"])')
  echo "status=$ST"
  [ "$ST" = "completed" ] && break
  [ "$ST" = "failed" ] && { echo "$S"; exit 1; }
  sleep 8
done

{/* 3 步:下载(--retry 兜底 status=completed 后的偶发 400)*/}
sleep 4
curl -sSL --retry 3 --retry-delay 4 \
  -H "Authorization: Bearer sk-your-api-key" \
  "https://api.apiyi.com/v1/videos/$TASK_ID/content" \
  -o output.mp4
ls -lh output.mp4

Node.js(原生 fetch + FormData)

import fs from 'node:fs';
import { FormData, File } from 'undici';

const API_KEY = 'sk-your-api-key';
const BASE_URL = 'https://api.apiyi.com/v1';

// 第 1 步:multipart 上传
const buffer = fs.readFileSync('./lighthouse.png');
const form = new FormData();
form.append('model', 'veo-3.1-fast-generate-preview');
form.append('prompt', '镜头从灯塔基座缓慢上升至塔顶,黄昏光线');
form.append('duration', '8');  // ⚠️ 字符串
form.append('size', '1280x720');
form.append('resolution', '720p');
form.append('aspectRatio', '16:9');
form.append('input_reference', new File([buffer], 'lighthouse.png', { type: 'image/png' }));

const submitResp = await fetch(`${BASE_URL}/videos`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}` },  // 不要手动加 Content-Type
    body: form
});
const { task_id } = await submitResp.json();
console.log(`Task ID: ${task_id}`);

// 第 2 步:轮询
let status = 'queued';
while (status !== 'completed' && status !== 'failed') {
    await new Promise(r => setTimeout(r, 8000));
    const s = await (await fetch(`${BASE_URL}/videos/${task_id}`, {
        headers: { 'Authorization': `Bearer ${API_KEY}` }
    })).json();
    status = s.status;
    console.log(`Status: ${status}, progress: ${s.progress ?? 0}%`);
}

if (status === 'failed') throw new Error('Generation failed');

// 第 3 步:下载(带重试)
await new Promise(r => setTimeout(r, 4000));
let videoBuffer;
for (let i = 0; i < 4; i++) {
    try {
        const resp = await fetch(`${BASE_URL}/videos/${task_id}/content`, {
            headers: { 'Authorization': `Bearer ${API_KEY}` }
        });
        if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
        videoBuffer = Buffer.from(await resp.arrayBuffer());
        break;
    } catch (e) {
        if (i === 3) throw e;
        await new Promise(r => setTimeout(r, 4000));
    }
}
fs.writeFileSync('output.mp4', videoBuffer);
console.log('Saved: output.mp4');

浏览器 JavaScript(FileInput 上传)

{/* 仅作演示,生产请走后端代理避免 Key 泄露;视频文件较大也不适合直接在浏览器下载 */}
const fileInput = document.querySelector('input[type=file]');
const file = fileInput.files[0];

const form = new FormData();
form.append('model', 'veo-3.1-fast-generate-preview');
form.append('prompt', '让这张静态画面动起来,缓慢推镜,自然环境音');
form.append('duration', '4');
form.append('size', '720x1280');
form.append('resolution', '720p');
form.append('aspectRatio', '9:16');
form.append('input_reference', file);

const submitResp = await fetch('https://api.apiyi.com/v1/videos', {
    method: 'POST',
    headers: { 'Authorization': 'Bearer sk-your-api-key' },
    body: form
});
const { task_id } = await submitResp.json();
console.log('Task ID:', task_id);

{/* 轮询完成后,把 /content 端点交给后端代理下载,再回流给前端展示 */}

参数说明速查

参数类型必填默认说明
input_referencefile参考图文件,字段名固定,仅 1 张,接受 image/jpeg / image/png / image/webp不接受远程 URL
modelstringveo-3.1-fast-generate-preview($0.3/次)或 veo-3.1-generate-preview($1.2/次)
promptstring描述视频动作 / 镜头 / 风格的提示词。不要传 generateAudio,音频意图写进 prompt
durationstring"8""4" / "6" / "8"1080p/4k 必须 "8"
sizestring1280x720输出像素
resolutionstring720p720p / 1080p / 4k
aspectRatiostring16:916:9(横)/ 9:16(竖)
seedint随机数种子(multipart 表单字段,传字符串数字也可)
multipart 与 JSON 模式的字段命名差异
  • JSON 模式下嵌套在 metadata.* 下(如 metadata.resolution
  • multipart 模式下平铺为表单字段(直接 resolution / aspectRatio / seed
  • 上面的代码示例已经按 multipart 约定写法
常见错误
  • input_reference 当作 Base64 字符串塞进 JSON body —— 必须走 multipart 文件字段
  • 字段名写成 image / reference / input_image —— 必须正好 input_reference
  • 同时传 2 张图 —— 服务端只取第一张,第二张被静默丢弃
  • 传远程 URL(如 https://cdn.../img.png)—— 不接受,必须文件或 Base64

响应格式

响应结构与 文生视频 完全一致:第 1 步返回 task_id + status: "queued",第 2 步轮询返回 status + 粗粒度 progress,第 3 步从 /content 端点下载 MP4 二进制。
{
  "id": "task_xxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "queued",
  "progress": 0,
  "created_at": 1775025000
}
⚠️ 响应字段陷阱
  • task_idid 同值,下游建议统一用 task_id
  • 没有直接的 video_url 字段,视频从 GET /v1/videos/{task_id}/content 下载
  • progress 只在 0 / 50 / 100 三档跳,不是线性进度
  • /content 端点在 status 刚翻 completed 后偶发 400,等 4 秒重试即可
  • 图生视频任务通常比同参数文生视频慢 10-30%(多了一次图像编码)
本端点是异步任务式入口,计费在任务进入 completed 时按模型名按次结算(与是否传 input_reference 无关,fast $0.3 / standard $1.2)。POST 提交、轮询查询、视频下载本身不计费,失败任务也不计费

授权

Authorization
string
header
必填

在 API易控制台获取的 API Key(默认分组 + 任意计费模式都能调通)

请求体

multipart/form-data
model
enum<string>
默认值:veo-3.1-fast-generate-preview
必填

模型 ID(按次计费):

  • veo-3.1-fast-generate-preview —— $0.3/次
  • veo-3.1-generate-preview —— $1.2/次
可用选项:
veo-3.1-fast-generate-preview,
veo-3.1-generate-preview
prompt
string
必填

视频生成提示词。重点描述如何让画面动起来:镜头运动、物体动作、光线变化、音频氛围。不要传 generateAudio,音频写进 prompt。

示例:

"镜头从灯塔基座缓慢上升至塔顶,黄昏光线,海浪轻拍礁石的声音"

input_reference
file
必填

参考图文件。字段名固定 input_reference,仅支持 1 张

接受格式:image/jpeg / image/png / image/webp不接受远程 URL,需要文件上传或 Base64。

duration
enum<string>
默认值:8

视频时长,字符串枚举"4" / "6" / "8"1080p / 4k 时必须 "8"

可用选项:
4,
6,
8
size
enum<string>
默认值:1280x720

输出像素,优先级低于 resolution

可用选项:
1280x720,
720x1280,
1920x1080,
1080x1920,
3840x2160,
2160x3840
resolution
enum<string>
默认值:720p

分辨率档位(multipart 模式下平铺为表单字段,优先级高于 size

可用选项:
720p,
1080p,
4k
aspectRatio
enum<string>
默认值:16:9

画面比例:16:9 横屏(默认)或 9:16 竖屏

可用选项:
16:9,
9:16
seed
string

随机数种子(multipart 表单字段,传字符串数字即可)。固定 seed 可让多次输出风格聚集,但不能字节级复现。

示例:

"20260521"

negativePrompt
string

反向提示词,推荐传 "blurry, watermark, distorted, low quality"

示例:

"blurry, watermark, distorted, low quality"

响应

任务已提交,返回 task_id 与 queued 状态

id
string

任务 ID(与 task_id 同值,下游建议统一用 task_id

示例:

"task_xxxxxxxxxxxxxxxx"

task_id
string

任务 ID,用于后续轮询和下载

示例:

"task_xxxxxxxxxxxxxxxx"

object
string

对象类型,固定 video

示例:

"video"

model
string

本次任务使用的模型 ID

示例:

"veo-3.1-fast-generate-preview"

status
enum<string>

任务状态:

  • queued —— 已提交,排队等待
  • in_progress —— 正在生成
  • completed —— 完成,可下载(/v1/videos/{task_id}/content
  • failed —— 失败(不计费),可重试
可用选项:
queued,
in_progress,
completed,
failed
示例:

"queued"

progress
integer

生成进度(粗粒度,只在 0 / 50 / 100 三档跳

示例:

0

created_at
integer

任务创建 Unix 时间戳(秒)

示例:

1775025000

completed_at
integer

任务完成 Unix 时间戳(秒),仅 completed 状态返回

示例:

1775025090