Skip to content

API 能力 Sora 2 视频生成(异步调用) Sora 2 异步视频生成 API - 完整的三步流程:提交请求、轮询状态、下载视频

概述 Sora 2 异步 API 采用标准的异步处理机制,适合需要更精细控制视频生成流程的场景。与同步流式 API 不同,异步 API 将视频生成分为三个独立步骤,让您可以更灵活地管理任务状态和下载时机。 异步 API 特别适合批量处理、后台任务、以及需要长时间等待的场景。如果您需要实时进度反馈,建议使用同步流式 API。

核心特性 独立的任务管理 提交后获得任务 ID,可随时查询状态 灵活的轮询策略 自定义轮询间隔,避免不必要的请求 可靠的视频下载 生成完成后独立下载,支持断点续传 批量处理支持 同时提交多个任务,并发处理更高效

完整流程 异步 API 采用三步流程:

Copy 第一步:提交请求 POST /v1/videos ↓ 返回 video_id

第二步:轮询状态(建议每 30 秒) GET /v1/videos/{video_id} ↓ submitted → in_progress → completed

第三步:下载视频 GET /v1/videos/{video_id}/content ↓ 保存 MP4 文件 典型生成时间:3-5 分钟。建议轮询间隔设置为 30 秒,最长等待时间设置为 10 分钟。

端点地址

Copy https://api.apiyi.com/v1/videos

第一步:提交视频生成请求

请求参数 参数 类型 必填 说明 prompt string ✅ 视频生成的文本描述,建议详细描述场景、动作、风格 model string ✅ 固定值:sora-2 size string ✅ 1280x720(横屏)或 720x1280(竖屏) seconds string ✅ 视频时长,可选值:10 或 15 input_reference file ❌ 参考图片文件(PNG/JPG/JPEG),可选,用于图生视频

文生视频示例

cURL

Python

JavaScript

Copy curl -X POST "https://api.apiyi.com/v1/videos"
-H "Authorization: YOUR_API_KEY"
-H "Accept: application/json"
-F "prompt=一只可爱的金毛犬在公园草地上追逐飞盘,阳光明媚,背景是绿树和蓝天"
-F "model=sora-2"
-F "size=1280x720"
-F "seconds=10"

图生视频示例 支持上传参考图片,生成基于图片的视频。

cURL

Python

Copy curl -X POST "https://api.apiyi.com/v1/videos"
-H "Authorization: YOUR_API_KEY"
-H "Accept: application/json"
-F "prompt=参考配图,使得动物们活跃起来,在场地里绕场一周的追逐"
-F "model=sora-2"
-F "size=1280x720"
-F "seconds=10"
-F "input_reference=@/path/to/image.png"

响应格式

Copy { "id": "video_abc123def456", "status": "submitted", "progress": 0, "prompt": "一只可爱的金毛犬在公园草地上追逐飞盘,阳光明媚,背景是绿树和蓝天", "model": "sora-2", "size": "1280x720", "seconds": "10", "created_at": 1704067200, "url": null, "completed_at": null }

第二步:轮询查询视频状态 提交请求后,需要定期轮询查询视频生成状态。

请求方式

Copy GET /v1/videos/

查询示例

cURL

Python

JavaScript

Copy curl -X GET "https://api.apiyi.com/v1/videos/video_abc123def456"
-H "Authorization: YOUR_API_KEY"

状态说明 状态 说明 下一步操作 submitted 请求已提交,等待处理 继续轮询查询 in_progress 视频生成中 继续轮询查询,可查看进度百分比 completed 视频生成完成 可以下载视频 failed 视频生成失败 检查错误信息,重新提交

生成中的响应示例

Copy { "id": "video_abc123def456", "status": "in_progress", "progress": 45, "prompt": "一只可爱的金毛犬在公园草地上追逐飞盘,阳光明媚,背景是绿树和蓝天", "model": "sora-2", "size": "1280x720", "seconds": "10", "created_at": 1704067200, "url": null, "completed_at": null }

完成后的响应示例

Copy { "id": "video_abc123def456", "status": "completed", "progress": 100, "prompt": "一只可爱的金毛犬在公园草地上追逐飞盘,阳光明媚,背景是绿树和蓝天", "model": "sora-2", "size": "1280x720", "seconds": "10", "created_at": 1704067200, "url": "https://api.apiyi.com/v1/videos/video_abc123def456/content", "completed_at": 1704067500 }

第三步:下载生成的视频 视频生成完成后(status 为 completed),可以下载视频文件。

请求方式

Copy GET /v1/videos/{video_id}/content

下载示例

cURL

Python

JavaScript

Copy curl -X GET "https://api.apiyi.com/v1/videos/video_abc123def456/content"
-H "Authorization: YOUR_API_KEY"
-o video.mp4 视频文件可能在一段时间后过期,建议生成完成后立即下载并保存到本地。

完整流程示例 以下是完整的三步流程集成示例:

Python 完整流程

Bash 完整流程

Copy import requests import time import os from datetime import datetime

API 配置

BASE_URL = "https://api.apiyi.com/v1/videos" API_KEY = "YOUR_API_KEY"

参数配置

IMAGE_PATH = './dog-and-cat.png' # 参考图片路径,设为 None 则为文生视频 PROMPT = '参考配图,使得动物们活跃起来,在场地里绕场一周的追逐' MODEL = 'sora-2' SIZE = '1280x720' SECONDS = '10'

轮询配置

POLL_INTERVAL = 30 MAX_WAIT_TIME = 600

def step1*submit_request(): """第一步:提交视频生成请求""" print("=" * 60) print("第一步:提交视频生成请求") print("=" _ 60)

files = {
    'prompt': (None, PROMPT),
    'model': (None, MODEL),
    'size': (None, SIZE),
    'seconds': (None, SECONDS)
}

headers = {
    'Accept': 'application/json',
    'Authorization': API_KEY
}

# 如果有图片,添加到请求中
if IMAGE_PATH and os.path.exists(IMAGE_PATH):
    print(f"模式:图片生成视频")
    print(f"图片: {IMAGE_PATH}")
    with open(IMAGE_PATH, 'rb') as f:
        files['input_reference'] = (
            os.path.basename(IMAGE_PATH),
            f,
            'image/png'
        )
        response = requests.post(BASE_URL, headers=headers, files=files)
else:
    print(f"模式:文字生成视频")
    response = requests.post(BASE_URL, headers=headers, files=files)

if response.status_code == 200:
    result = response.json()
    video_id = result.get('id')
    print(f"✅ 请求提交成功!")
    print(f"   视频ID: {video_id}")
    print(f"   状态: {result.get('status')}")
    print(f"   预计生成时间: 3-5 分钟")
    return video_id
else:
    print(f"❌ 请求失败: {response.status_code}")
    print(f"   响应: {response.text}")
    return None

def step2*poll_status(video_id): """第二步:轮询查询视频生成状态""" print("\n" + "=" * 60) print("第二步:查询视频生成状态") print("=" _ 60)

headers = {'Authorization': API_KEY}
status_url = f"{BASE_URL}/{video_id}"
start_time = time.time()

while True:
    elapsed_time = time.time() - start_time

    if elapsed_time > MAX_WAIT_TIME:
        print(f"⏱️ 超时:已等待 {MAX_WAIT_TIME} 秒")
        return False

    response = requests.get(status_url, headers=headers)

    if response.status_code == 200:
        result = response.json()
        status = result.get('status')
        progress = result.get('progress', 0)

        print(f"\n🔍 查询状态... (已等待 {int(elapsed_time)} 秒)")
        print(f"   状态: {status}")
        print(f"   进度: {progress}%")

        if status == 'completed':
            print(f"✅ 视频生成完成!")
            print(f"   视频URL: {result.get('url')}")
            return True
        elif status == 'failed':
            print(f"❌ 视频生成失败")
            return False
        else:
            print(f"⏳ 等待 {POLL_INTERVAL} 秒后继续查询...")
            time.sleep(POLL_INTERVAL)
    else:
        print(f"❌ 状态查询失败: {response.status_code}")
        time.sleep(POLL_INTERVAL)

def step3*download_video(video_id, output_path=None): """第三步:下载生成的视频""" print("\n" + "=" * 60) print("第三步:下载视频") print("=" _ 60)

if output_path is None:
    output_path = f"sora_video_{video_id.split('_')[-1]}.mp4"

headers = {'Authorization': API_KEY}
content_url = f"{BASE_URL}/{video_id}/content"

print(f"📥 开始下载视频...")
response = requests.get(content_url, headers=headers, stream=True)

if response.status_code == 200:
    total_size = int(response.headers.get('content-length', 0))

    with open(output_path, 'wb') as f:
        if total_size == 0:
            f.write(response.content)
        else:
            downloaded = 0
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)
                    downloaded += len(chunk)
                    percent = (downloaded / total_size) * 100
                    print(f"\r   下载进度: {percent:.1f}%", end='')

    print(f"\n✅ 视频下载成功!")
    print(f"   保存路径: {os.path.abspath(output_path)}")
    print(f"   文件大小: {os.path.getsize(output_path)} 字节")
    return True
else:
    print(f"❌ 下载失败: {response.status_code}")
    return False

def main(): """完整的异步流程""" print("\n🎬 开始 Sora-2 视频生成完整流程") print(f"⏰ 开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")

# 第一步:提交请求
video_id = step1_submit_request()
if not video_id:
    print("\n❌ 流程终止:视频请求提交失败")
    return

# 第二步:轮询状态
success = step2_poll_status(video_id)
if not success:
    print("\n❌ 流程终止:视频生成未完成")
    return

# 第三步:下载视频
success = step3_download_video(video_id)

if success:
    print("\n" + "=" * 60)
    print("🎉 完整流程执行成功!")
    print("=" * 60)
    print(f"⏰ 结束时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

if name == "main": main()

最佳实践

Prompt 编写建议 好的 Prompt 应该包含:场景描述、主体动作、镜头风格、艺术风格。 优秀示例:

Copy 一只可爱的金毛犬在绿色草地上追逐红色飞盘,阳光明媚, 背景是蓝天白云和绿树,运动流畅,特写镜头跟随犬的动作, 电影级画质,暖色调 不佳示例:

Copy 狗追飞盘

参考图片建议 分辨率:建议 1280x720 或更高 格式:PNG 或 JPG 文件大小:< 10MB 内容:清晰、主体明确、光线良好 匹配度:图片内容应与 prompt 描述相关

轮询策略建议 推荐设置 轮询间隔:30 秒 最长等待:10 分钟(600 秒) 典型耗时:3-5 分钟 避免设置 轮询间隔:< 30 秒(可能触发限流) 最长等待:< 5 分钟(可能提前放弃)

错误重试策略

Copy import time

def retry_with_backoff(func, max_retries=3): """指数退避重试策略""" for i in range(max_retries): try: return func() except Exception as e: if i == max_retries - 1: raise wait_time = 2 ** i # 1s, 2s, 4s print(f"重试 {i+1}/{max_retries},等待 {wait_time} 秒...") time.sleep(wait_time)

配额和限制 限制项 值 说明 请求速率 10 次/分钟 超过会返回 429 错误 并发任务 5 个 同时处理的视频数量 视频时长 10 或 15 秒 不支持其他时长 图片大小 < 10MB 建议 < 5MB Prompt 长度 < 1000 字符 建议 100-300 字符

错误处理

常见错误码 状态码 说明 解决方案 200 成功 - 400 请求参数错误 检查必填参数是否完整 401 认证失败 检查 API Key 是否正确 403 无权限 检查 API Key 是否有效或余额不足 404 资源不存在 检查 video_id 是否正确 429 请求过于频繁 增加轮询间隔 500 服务器错误 稍后重试