跳转到主要内容

方案说明

Veo 3.1 官方 API 转发方案已接入 api.laozhang.ai,并兼容 OpenAI Videos API 风格。新接入请单独创建新令牌,令牌使用 默认分组,计费模式选择 Pay-per-request。本文说明接口、参数、价格和代码示例。

价格优势

Veo 3.1 官转使用 Pay-per-request 计费,在支持的时长和分辨率组合内统一价格,不按时长或分辨率额外加价。按 Google Gemini API Pricing 公开价格测算,Google 官方 Veo 3.1 以秒计费;以下折扣按 8 秒视频计算。
模型我们价格Google 官方 8 秒 1080p便宜约Google 官方 8 秒 4K便宜约
veo-3.1-fast-generate-preview$0.3/次$0.9668.8%$2.4087.5%
veo-3.1-generate-preview$1.2/次$3.2062.5%$4.8075.0%
该方案使用和 Sora2 官转一致的 OpenAI Videos API 风格:
步骤方法路径返回
创建视频任务POST/v1/videosJSON 任务对象
查询任务状态GET/v1/videos/{id}JSON 状态对象
兼容查询任务状态GET/v1/video/generations/{id}JSON 状态对象
下载视频结果GET/v1/videos/{id}/contentvideo/mp4 字节流
文生视频可以直接使用 OpenAI SDK;单首帧图生视频请使用 input_reference 上传本地图片文件。首尾帧请使用 JSON 请求体里的 imagesmetadata.lastFrame Data URI。多参考图字段当前不要作为生产能力接入。
2026-06-27 根据上游提供的 JSON 示例重新验证:images[] + metadata.lastFrame 可稳定生成匹配首帧和尾帧的视频,720p 与 1080p 均通过抽帧检查。注意字段大小写必须是 lastFrame,不是 lastframe;请求体必须是 JSON,不是 multipart;duration 请传字符串 "8",不要传数字 8metadata.referenceImages 仍会返回 referenceImage isn't supported by this model,暂不开放多参考图。
不要使用旧 Veo-3.1 同步接口、旧 Chat Completions 示例或旧 veo-3.1 / veo-3.1-fast / veo-3.1-fl 模型名。官转方案只使用本文列出的模型名和 /v1/videos 任务接口。

令牌创建规则

配置项选择
控制台入口令牌管理 → 新增令牌
分组默认分组
Billing modePay-per-request
建议为 Veo 3.1 官转单独创建新令牌,便于后续核对消费
Veo 3.1 官转使用 Pay-per-request 计费模式,在支持的时长和分辨率组合内统一价格,不按时长或分辨率额外加价。

支持模型

模型单次价格说明推荐用途
veo-3.1-fast-generate-preview$0.3Veo 3.1 Fast 预览模型快速测试、批量草稿、成本优先
veo-3.1-generate-preview$1.2Veo 3.1 标准预览模型质量优先、正式素材、复杂镜头

OpenAI SDK 快速接入

如果只做文生视频或单图图生视频,优先使用 OpenAI SDK。base_url 固定为 https://api.laozhang.ai/v1
import time
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.laozhang.ai/v1",
)

video = client.videos.create(
    model="veo-3.1-fast-generate-preview",
    prompt="A rainy neon street, a delivery robot driving through reflections, cinematic camera pan",
    seconds="4",
    size="1280x720",
)

video_id = video.id

while True:
    video = client.videos.retrieve(video_id)
    if video.status == "completed":
        break
    if video.status == "failed":
        raise RuntimeError(video.error)
    time.sleep(10)

content = client.videos.download_content(video_id)
content.write_to_file("veo-output.mp4")
单张图片转视频时,把图片文件作为 input_reference 传入:
with open("reference.png", "rb") as image_file:
    video = client.videos.create(
        model="veo-3.1-fast-generate-preview",
        prompt="Animate this reference image with a gentle camera push-in",
        seconds="4",
        size="1280x720",
        input_reference=image_file,
    )

参数说明

基础参数

参数类型必填说明
modelstringveo-3.1-fast-generate-previewveo-3.1-generate-preview
promptstring视频描述文本
secondsstring视频时长,推荐固定传 "8"
durationstring视频时长,multipart 和 JSON 首尾帧请求都建议传 "8";不要传数字 8
sizestring输出尺寸,例如 1280x720720x12801920x10801080x19203840x2160
resolutionstring720p1080p4k
aspectRatiostring16:99:16
metadatastring / objectmultipart 中传 JSON 字符串;JSON 首尾帧请求中传对象,例如 {"lastFrame":"data:image/jpeg;base64,..."}
negativePromptstring反向提示词,例如 blurry, watermark, distorted;图生视频请求建议不传
seedstring随机种子,便于复现相近效果
input_referencefile已验证的单首帧图生视频字段,使用 multipart/form-data 上传
imagesstring[]JSON 首尾帧请求的首帧数组,元素为 Data URI
metadata.lastFramestringJSON 首尾帧请求的尾帧 Data URI,字段名区分大小写
referenceImages / metadata.referenceImagesfile / string[]当前上游返回 referenceImage 不支持,暂不开放
reference_image / reference_imagesfile兼容多参考图字段,当前不可用
referenceType / reference_typestring多参考图类型字段,当前不要单独依赖
videofile视频扩展字段,上传已有 MP4 作为续写参考
不要传 generateAudio 参数。Veo 3 / Veo 3.1 系列模型原生带音频,但接口不支持通过 generateAudio 开关音频;传入该字段可能返回 INVALID_ARGUMENT。如需控制音频内容,请在 prompt 中描述对白、环境音、音效或音乐风格。

时长和分辨率

场景建议参数
4 秒横屏 720pseconds="4"size="1280x720"resolution="720p"aspectRatio="16:9"
8 秒横屏 720pseconds="8"size="1280x720"resolution="720p"aspectRatio="16:9"
8 秒横屏 1080pseconds="8"size="1920x1080"resolution="1080p"aspectRatio="16:9"
8 秒竖屏 1080pseconds="8"size="1080x1920"resolution="1080p"aspectRatio="9:16"
8 秒横屏 4Kseconds="8"duration="8"size="3840x2160"resolution="4k"aspectRatio="16:9"metadata='{"durationSeconds":8,"resolution":"4k","aspectRatio":"16:9"}'
secondsduration 建议传字符串,不要传数字。快速测试可以用 720p + 4s;生产接入推荐固定传 8 秒;1080p4k 只支持 8 秒。图生视频请上传本地图片文件,不建议直接传远程图片 URL。
参数限制:1080p4k 只能与 8 秒组合使用,不要与 4 秒或 6 秒组合。4K 请求请同时传 metadata.resolution="4k",否则最终下载文件可能按 1080p 输出。
4K 请求按统一价计费;如需验收原生 4K,请下载 MP4 并以媒体信息为准。不要仅凭任务创建参数判断最终文件分辨率。

文生视频

创建任务

curl -X POST "https://api.laozhang.ai/v1/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model="veo-3.1-fast-generate-preview" \
  -F prompt="A cinematic shot of a lighthouse at sunset, ocean waves hitting the rocks, stable slow camera push-in" \
  -F seconds="8" \
  -F duration="8" \
  -F size="1280x720" \
  -F resolution="720p" \
  -F aspectRatio="16:9" \
  -F 'metadata={"durationSeconds":8,"resolution":"720p","aspectRatio":"16:9"}' \
  -F negativePrompt="blurry, watermark, distorted, low quality" \
  -F seed="20260520"

创建响应

{
  "id": "task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "queued",
  "progress": 0,
  "created_at": 1779283975
}

图生视频

图生视频使用同一个创建接口。单首帧图生视频用 multipart 的 input_reference;首尾帧生成用 JSON 请求体的 images[] + metadata.lastFrame。不要用 multipart 的 last_frame / lastFrame 文件字段替代 JSON metadata.lastFrame
curl -X POST "https://api.laozhang.ai/v1/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model="veo-3.1-generate-preview" \
  -F prompt="Animate the reference image with a gentle camera push-in, subtle background parallax, cinematic lighting" \
  -F seconds="8" \
  -F duration="8" \
  -F size="1280x720" \
  -F resolution="720p" \
  -F aspectRatio="16:9" \
  -F 'metadata={"durationSeconds":8,"resolution":"720p","aspectRatio":"16:9"}' \
  -F seed="20260520" \
  -F input_reference="@reference.jpg;type=image/jpeg"

4K 横屏图生视频

4K 横屏图生视频需要上传 16:9 的参考图,并同时传 resolution="4k"metadata.resolution="4k"
curl -X POST "https://api.laozhang.ai/v1/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model="veo-3.1-fast-generate-preview" \
  -F prompt="Animate the 4K reference image with a slow cinematic camera push-in, subtle parallax, crisp details, stable lighting" \
  -F seconds="8" \
  -F duration="8" \
  -F size="3840x2160" \
  -F resolution="4k" \
  -F aspectRatio="16:9" \
  -F 'metadata={"durationSeconds":8,"resolution":"4k","aspectRatio":"16:9"}' \
  -F seed="20260521" \
  -F input_reference="@reference-4k.jpg;type=image/jpeg"

首尾帧生成

首尾帧必须使用 JSON 请求体。images 传首帧 Data URI 数组,metadata.lastFrame 传尾帧 Data URI。duration 建议传字符串,例如 "8",避免兼容层把数字类型拒绝。实测 size="1920x1080"duration="8" 返回 1920×1080、8 秒 MP4,首帧和尾帧抽帧均匹配输入。
curl -X POST "https://api.laozhang.ai/v1/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3.1-fast-generate-preview",
    "prompt": "Create an 8-second cinematic transition with smooth camera motion. Do not add captions or on-screen text.",
    "size": "1920x1080",
    "duration": "8",
    "images": ["data:image/jpeg;base64,BASE64_FIRST_FRAME"],
    "metadata": {
      "lastFrame": "data:image/jpeg;base64,BASE64_LAST_FRAME"
    }
  }'

多参考图

多参考图当前不可用。按上游示例传 metadata.referenceImages 时,Fast 和 Standard 模型都会返回 referenceImage isn't supported by this model / INVALID_ARGUMENT。生产接入请不要开放素材参考图;如需首尾帧,请使用上面的 JSON metadata.lastFrame 写法。

视频扩展

视频扩展使用 video 文件字段上传已有 MP4,建议固定使用 8 秒请求。该模式会按提示词续写视频风格和内容,不保证逐帧无缝拼接原视频。
curl -X POST "https://api.laozhang.ai/v1/videos" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F model="veo-3.1-fast-generate-preview" \
  -F prompt="Extend the uploaded rainy city video into a continued shot with the same neon street style" \
  -F video="@source.mp4;type=video/mp4" \
  -F seconds="8" \
  -F duration="8" \
  -F size="1280x720" \
  -F resolution="720p" \
  -F aspectRatio="16:9" \
  -F 'metadata={"durationSeconds":8,"resolution":"720p","aspectRatio":"16:9"}'
图片尺寸建议与 size 参数保持一致,例如 size=1280x720 时上传 1280×720 图片。支持 JPEG、PNG、WebP。视频扩展请上传 MP4 文件,下载结果时要按大文件处理并加入重试。

查询状态

创建任务后保存返回的 idtask_id,然后轮询状态。
curl "https://api.laozhang.ai/v1/videos/task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Authorization: Bearer YOUR_API_KEY"
进行中响应:
{
  "id": "task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "in_progress",
  "progress": 50,
  "created_at": 1779283975
}
完成响应:
{
  "id": "task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "completed",
  "progress": 100,
  "created_at": 1779283975,
  "completed_at": 1779284026
}

状态值

状态说明
queued已排队
in_progress生成中
completed已完成,可下载
failed生成失败

兼容查询任务状态

如果已有代码使用旧的 video generations 查询路径,可以调用兼容接口:
curl "https://api.laozhang.ai/v1/video/generations/task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Authorization: Bearer YOUR_API_KEY"
该接口返回任务状态对象:
{
  "id": "task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "object": "video",
  "model": "veo-3.1-fast-generate-preview",
  "status": "completed",
  "progress": 100,
  "created_at": 1779283975,
  "completed_at": 1779284026
}
兼容查询接口不返回独立公开视频 URL。视频结果请通过 /v1/videos/{id}/content 下载。

下载视频

任务完成后,通过 /content 获取 MP4 字节流。接口返回的是视频文件内容,不是公开视频 URL。
curl -L "https://api.laozhang.ai/v1/videos/task_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/content" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o veo-3-1-output.mp4
GET /v1/videos/{id} 返回 completed 后,视频文件可能仍有短暂落盘延迟。如果下载接口返回 task status is IN_PROGRESS、400 JSON 错误或短暂断流,等待 10-20 秒后重试即可。4K 文件较大,生产代码建议使用流式下载并设置重试。

Python 完整示例

import base64
import json
import mimetypes
from pathlib import Path
import time

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.laozhang.ai"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}"
}


def video_metadata(seconds, resolution, aspect_ratio):
    payload = {
        "durationSeconds": int(seconds),
        "resolution": resolution,
        "aspectRatio": aspect_ratio,
    }
    return json.dumps(payload)


def form_items(fields):
    return [(key, (None, value)) for key, value in fields.items()]


def data_uri(image_path):
    mime_type = mimetypes.guess_type(image_path)[0] or "image/jpeg"
    with open(image_path, "rb") as image_file:
        encoded = base64.b64encode(image_file.read()).decode("ascii")
    return f"data:{mime_type};base64,{encoded}"


def create_text_video(
    prompt,
    model="veo-3.1-fast-generate-preview",
    seconds="8",
    size="1280x720",
    resolution="720p",
    aspect_ratio="16:9",
):
    fields = {
        "model": model,
        "prompt": prompt,
        "seconds": seconds,
        "duration": seconds,
        "size": size,
        "resolution": resolution,
        "aspectRatio": aspect_ratio,
        "metadata": video_metadata(seconds, resolution, aspect_ratio),
        "negativePrompt": "blurry, watermark, distorted, low quality",
    }
    response = requests.post(
        f"{BASE_URL}/v1/videos",
        headers=HEADERS,
        files={key: (None, value) for key, value in fields.items()},
        timeout=180,
    )
    response.raise_for_status()
    return response.json()


def create_image_video(
    prompt,
    image_path,
    model="veo-3.1-generate-preview",
    seconds="8",
    size="1280x720",
    resolution="720p",
    aspect_ratio="16:9",
):
    fields = {
        "model": model,
        "prompt": prompt,
        "seconds": seconds,
        "duration": seconds,
        "size": size,
        "resolution": resolution,
        "aspectRatio": aspect_ratio,
        "metadata": video_metadata(seconds, resolution, aspect_ratio),
    }
    with open(image_path, "rb") as image_file:
        files = form_items(fields)
        files.append(("input_reference", (Path(image_path).name, image_file, "image/jpeg")))
        response = requests.post(
            f"{BASE_URL}/v1/videos",
            headers=HEADERS,
            files=files,
            timeout=180,
        )
    response.raise_for_status()
    return response.json()


def create_first_last_frame_video(
    prompt,
    first_frame_path,
    last_frame_path,
    model="veo-3.1-fast-generate-preview",
    size="1920x1080",
):
    payload = {
        "model": model,
        "prompt": prompt,
        "size": size,
        "duration": "8",
        "images": [data_uri(first_frame_path)],
        "metadata": {
            "lastFrame": data_uri(last_frame_path),
        },
    }
    response = requests.post(
        f"{BASE_URL}/v1/videos",
        headers={**HEADERS, "Content-Type": "application/json"},
        json=payload,
        timeout=180,
    )
    response.raise_for_status()
    return response.json()


def create_video_extension(
    prompt,
    video_path,
    model="veo-3.1-fast-generate-preview",
):
    fields = {
        "model": model,
        "prompt": prompt,
        "seconds": "8",
        "duration": "8",
        "size": "1280x720",
        "resolution": "720p",
        "aspectRatio": "16:9",
        "metadata": video_metadata("8", "720p", "16:9"),
    }
    with open(video_path, "rb") as video_file:
        files = form_items(fields)
        files.append(("video", (Path(video_path).name, video_file, "video/mp4")))
        response = requests.post(
            f"{BASE_URL}/v1/videos",
            headers=HEADERS,
            files=files,
            timeout=180,
        )
    response.raise_for_status()
    return response.json()


def wait_for_video(task_id, timeout=900, interval=15):
    start = time.time()
    while time.time() - start < timeout:
        response = requests.get(
            f"{BASE_URL}/v1/videos/{task_id}",
            headers=HEADERS,
            timeout=60,
        )
        response.raise_for_status()
        payload = response.json()

        status = payload.get("status")
        progress = payload.get("progress", 0)
        print(f"status={status}, progress={progress}")

        if status == "completed":
            return payload
        if status == "failed":
            raise RuntimeError(f"video generation failed: {payload}")

        time.sleep(interval)

    raise TimeoutError("video generation timed out")


def download_video(task_id, output_path, retries=8, interval=10):
    last_error = None
    for _ in range(retries):
        response = requests.get(
            f"{BASE_URL}/v1/videos/{task_id}/content",
            headers=HEADERS,
            stream=True,
            timeout=600,
        )
        if response.status_code == 200:
            with open(output_path, "wb") as output_file:
                for chunk in response.iter_content(chunk_size=1024 * 1024):
                    if chunk:
                        output_file.write(chunk)
            return output_path

        last_error = response.text
        if "IN_PROGRESS" not in response.text and "in_progress" not in response.text:
            response.raise_for_status()
        time.sleep(interval)

    raise RuntimeError(f"download failed: {last_error}")


if __name__ == "__main__":
    task = create_text_video(
        prompt="A cinematic lighthouse at sunset, ocean waves, slow camera push-in",
        model="veo-3.1-fast-generate-preview",
        seconds="8",
        size="1280x720",
    )
    task_id = task.get("id") or task.get("task_id")
    wait_for_video(task_id)
    download_video(task_id, "veo-output.mp4")

常见问题

/v1/videos/{id}/content 返回的是 video/mp4 字节流,不是公开视频 URL。/v1/video/generations/{id} 返回任务状态对象,不返回独立公开视频 URL。生产环境中可以由服务端下载后转存到自己的 OSS/CDN,再返回业务侧 URL。
Veo 3.1 官转使用默认分组即可。建议新建独立令牌,并将 Billing mode 选择为 Pay-per-request,方便后续账单核对。
统一按 Pay-per-request 计费,不按秒数或分辨率拆分价格。veo-3.1-fast-generate-preview$0.3/次veo-3.1-generate-preview$1.2/次。生产接入推荐固定传 8 秒;1080p4k 必须使用 8 秒。4K 请求请同时传 metadata.resolution="4k"
可以接入两类已验证图片控制:单首帧使用 multipart input_reference,首尾帧使用 JSON images[] + metadata.lastFrame。不要把 metadata.referenceImages 当作多素材图能力接入;当前上游会返回 referenceImage 不支持。
支持。使用 video 文件字段上传 MP4,并固定传 seconds="8"duration="8"。视频扩展会按提示词续写风格和内容,不保证逐帧无缝拼接原视频。
不要传 generateAudio。Veo 3 / Veo 3.1 系列原生带音频,但接口不支持通过 generateAudio 参数开关音频;如需控制声音,请写进 prompt
不建议。Veo 3.1 官转应按 Sora2 官转同款 /v1/videos 任务接口接入。