跳转到正文
GetAPI
简体中文
菜单

GetAPI.ONE

使用 ONE 任务 API 生成视频

提交 OpenAI 形状的视频任务,保存公开任务 ID,通过 ONE 的准确状态端点轮询至终止状态,并仅在完成后获取内容。

计费前确认协议

  • 选择当前目录中明确声明 OpenAI 视频端点的模型。
  • 查看实时价格与模型支持的输入字段;视频任务可能异步执行并产生费用。
  • 首次接受计费的测试使用短小、低风险的提示词。
text
POST https://www.getapi.one/v1/videos
GET https://www.getapi.one/v1/videos/{task_id}
GET https://www.getapi.one/v1/videos/{task_id}/content

提交、轮询与获取

  1. 向 POST https://www.getapi.one/v1/videos 提交请求,并准确保存返回的任务 ID。
  2. 以固定间隔和有上限的检查次数轮询 GET https://www.getapi.one/v1/videos/{task_id};等待期间不要新建任务。
  3. queued 或 in_progress 时继续;仅 completed 视为成功停止。
  4. failed 时停止并展示错误。未知状态应按非成功处理,并保留响应用于诊断。
  5. completed 后再获取 GET https://www.getapi.one/v1/videos/{task_id}/content。
  6. 在累计上限内以固定大小分块写入内容。示例使用 512 MiB 本地上限,并在读取、验证、写入或取消失败时删除部分文件。
提交任务
curl --fail-with-body https://www.getapi.one/v1/videos \
  -H "Authorization: Bearer $GETAPI_ONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<OPENAI_VIDEO_MODEL_ID_FROM_CURRENT_CATALOG>",
    "prompt": "A five-second locked-camera product turntable on a neutral background"
  }' > video-submit.json
最多轮询 30 次,仅 completed 后获取
import json
import os
import time
from pathlib import Path
from urllib.parse import quote
from urllib.request import Request, urlopen

base_url = "https://www.getapi.one"
api_key = os.environ["GETAPI_ONE_API_KEY"]
submitted = json.loads(Path("video-submit.json").read_text(encoding="utf-8"))
task_id = submitted.get("id") or submitted.get("task_id")
if not task_id:
    raise ValueError("Submit response did not contain id or task_id")

safe_id = quote(task_id, safe="")
headers = {"Authorization": f"Bearer {api_key}"}
for attempt in range(30):
    request = Request(f"{base_url}/v1/videos/{safe_id}", headers=headers)
    with urlopen(request, timeout=30) as response:
        task = json.load(response)
    status = task.get("status")
    if status == "completed":
        break
    if status == "failed":
        raise RuntimeError(f"video task failed: {task.get('error')}")
    if status not in {"queued", "in_progress"}:
        raise RuntimeError(f"unknown non-success status: {status}")
    if attempt == 29:
        raise TimeoutError("video was not complete after 30 status checks")
    time.sleep(10)

content_request = Request(
    f"{base_url}/v1/videos/{safe_id}/content",
    headers=headers,
)
MAX_VIDEO_BYTES = 512 * 1024 * 1024
CHUNK_BYTES = 1024 * 1024
output_path = Path("result.mp4")
created_output = False
with urlopen(content_request, timeout=60) as response:
    content_type = response.headers.get_content_type()
    if not content_type.startswith("video/"):
        raise ValueError(f"unexpected content type: {content_type}")
    try:
        output = output_path.open("xb")
        created_output = True
        with output:
            total_bytes = 0
            while chunk := response.read(CHUNK_BYTES):
                total_bytes += len(chunk)
                if total_bytes > MAX_VIDEO_BYTES:
                    raise ValueError("video exceeds the local 512 MiB limit")
                output.write(chunk)
    except BaseException:
        if created_output:
            output_path.unlink(missing_ok=True)
        raise

实现状态机

状态客户端动作
queued等待固定间隔后,在有上限的检查次数内查询同一任务 ID。
in_progress若有进度则展示,并继续轮询。
completed停止轮询并请求内容端点。
failed停止轮询,记录安全的错误详情,并要求用户明确重试。

验证预期结果

  • 提交响应提供任务 ID,客户端以足够持久的方式保存它。
  • 每次状态请求使用同一 ID,且不会创建重复任务。
  • 下载内容具有视频 Content-Type,并且仅在 completed 后打开。

避免重复任务并恢复

  • 提交超时时不要盲目重提:先检查是否已生成任务 ID 或控制台记录。
  • 轮询遇到 404 时,核对公开任务 ID、准确的单复数路径与同一账户密钥。
  • failed 时,在修改输入前保留模型、安全的请求摘要、任务 ID 与错误详情。

保护媒体任务与结果

  • 将密钥与任务查询保留在已鉴权后端。
  • 转发前按所选模型契约校验提示词、上传文件、时长、尺寸与数量。
  • 将获批结果存入受控存储;不要假设内容 URL 永久有效或适合公开。
  • 将累计下载上限设置在内存与存储预算以内,以固定大小分块写入,并在下载未完成时清理部分产物。

下一步