# Gemini Omni 视频生成
> 文生视频、图生视频、视频编辑与延长
> 不需要传时长，由模型自行决定，通常 3 到 10 秒
> 可以用上一次的任务 ID 做多轮对话式修改
`POST /v1/videos`
## 认证
- `Authorization` (string / 必填) — 所有接口均使用 Bearer Token 进行认证。 获取 API Key：[访问控制台](https://api.oairoute.com/keys) 创建。 请求时在请求头中添加： ```http Authorization: Bearer YOUR_OAIRoute_KEY ```
## 请求参数
> **Note:** 
> 提交成功只返回任务 ID，不含视频本身。拿成片用 `task_id` 轮询[获取任务状态](../tasks/status.html)，成片地址在 `result.videos[0].url`，该地址约 24 小时后过期，请及时转存。
- `model` (string / 必填) — 取值 `gemini-omni-flash-preview` 或 `gemini-omni-1.1-flash`。
- `prompt` (string / 条件必填) — 文生视频时是场景描述；图生视频、视频编辑时是要执行的动作或风格指令。 `prompt` 与媒体字段至少要有一个。
- `resolution` (string / 可选) — 输出分辨率，取值 `360p`、`720p`、`1080p`、`4k`，默认 `720p`，大小写不敏感。 `2160p` 按 `4k` 处理。`gemini-omni-flash-preview` 目前只支持 `720p`。
- `aspect_ratio` (string / 可选) — 输出画幅，取值 `16:9`、`9:16`，默认 `16:9`。 传其他值会静默回落为 `16:9`。带视频输入时该字段失效，比例跟随源视频。
- `image_urls` (string[] / 可选) — 1 张按首帧处理；多张按多主体或风格参考处理，需要在 `prompt` 里说明各自角色。 `gemini-omni-flash-preview` 最多 16 张，`gemini-omni-1.1-flash` 与帧图合计不超过 10 张。
- `first_frame_image` (string / 可选) — 首帧。单独传是首帧；与 `last_frame_image` 同传是首尾帧过渡。
- `last_frame_image` (string / 可选) — 尾帧，只能与 `first_frame_image` 一起使用。 单独传返回 `invalid_frame_images`；建议与首帧同比例并匹配 `aspect_ratio`。
- `image_with_roles` (object[] / 可选) — 带角色的图片数组，每项含 `url` 与 `role`。 `role` 取值 `first_frame`、`last_frame`、`reference`。`last_frame` 必须已有首帧。
- `video_urls` (string[] / 可选) — 要编辑或延长的视频。 `gemini-omni-flash-preview` 最多 1 段，`gemini-omni-1.1-flash` 最多 1 段且不超过 10 秒，只接受直链，不支持 YouTube 链接。与 `extend_from_task_id` 互斥。
- `metadata.task` (string / 可选) — 显式指定任务类型，取值 `text_to_video`、`image_to_video`、`reference_to_video`、`edit`、`extend`。 省略时由平台按输入推断。
- `extend_from_task_id` (string / 可选) — 上一次的任务 ID。必须是本人所有、已完成、且属于 Gemini Omni 的任务。与 `video_urls` 互斥。
- `nsfw_check` (boolean / 可选) — 为 `true` 时先做内容审查，默认 `false`。
## 模式判定
可以显式传 `metadata.task` 指定任务类型，也可以交给平台按输入推断。
只有提示词是文生视频；带 `image_urls` 是图生视频；带 `video_urls` 是视频编辑或延长；带 `extend_from_task_id` 是接续上一次的生成。
首尾帧两种写法二选一：用 `first_frame_image` / `last_frame_image`，或用 `image_with_roles` 里 `role` 为 `first_frame` / `last_frame` 的条目，不要同时用。
`image_urls` 与 `image_with_roles` 都带参考图时，以 `image_urls` 为准，两者不会合并。
## 支持的模型列表
| 模型 ID | 定位 |
|---|---|
| `gemini-omni-1.1-flash` | 当前主力，最高 4K，支持视频编辑与多轮接续 |
| `gemini-omni-flash-preview` | 预览版，最多 16 张参考图，目前固定 720p |
| `omni-flash-ext` | 预览版的延长专用入口 |
## 使用限制
- 没有 `duration` 参数，长度由模型决定
- 带视频输入时 `aspect_ratio` 不生效
- `last_frame_image` 不能单独使用
- `video_urls` 与 `extend_from_task_id` 不能同时传
- 成片链接在 `result.videos[].url` 里以数组形式返回，并按 `expires_at` 过期
## 响应
提交成功返回统一的受理结构：
```json
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
- `code` (integer / 总是返回) — 状态码，`200` 表示任务已受理。
- `data` (array / 总是返回) — 本次提交的任务列表，逐项提交时按顺序排列。
- `data[].status` (string / 总是返回) — 受理状态，提交成功时为 `submitted`。
- `data[].task_id` (string / 总是返回) — 任务 ID，用它轮询结果。
## 错误
| HTTP | type | 说明 |
|---|---|---|
| 400 | invalid_request_error | 请求参数无效，或参数组合冲突 |
| 401 | authentication_error | 身份验证失败，需检查 API Key |
| 402 | payment_required | 账户余额不足，需先充值 |
| 429 | rate_limit_error | 调用频率过高，稍后重试 |
参数错误在提交阶段同步返回，不创建任务、不扣费。
更多状态码与重试建议见[错误码与限流](../../support/errors.html)，常见报错的排查步骤见[常见问题](../../support/faq.html)。
## 查询任务
`GET /v1/tasks/{task_id}` 返回任务进度与结果，`status` 为 `completed` 时成片地址在 `result.videos[0].url`，元素带 `expires_at` 过期时间戳。
建议每 5 到 10 秒轮询一次，客户端总超时设为 10 到 15 分钟。`status` 取值 `pending`、`processing`、`completed`、`failed`、`cancelled`，以状态判定完成，不要依赖 `progress`。
失败任务自动退回费用，`error.message` 给出原因。
**文生视频{Text to video}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "gemini-omni-1.1-flash",
  "prompt": "雨夜的老街，霓虹灯在水洼里碎成一片，镜头缓慢跟拍一个撑伞的人",
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}'
```
**文生视频{Text to video}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "gemini-omni-1.1-flash",
  "prompt": "雨夜的老街，霓虹灯在水洼里碎成一片，镜头缓慢跟拍一个撑伞的人",
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**文生视频{Text to video}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "gemini-omni-1.1-flash",
  "prompt": "雨夜的老街，霓虹灯在水洼里碎成一片，镜头缓慢跟拍一个撑伞的人",
  "resolution": "1080p",
  "aspect_ratio": "16:9"
}),
});
console.log(await res.json());
```
**200 文生视频{Text to video}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**图生视频{Image to video}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "gemini-omni-1.1-flash",
  "prompt": "让人物缓缓转头，看向窗外",
  "image_urls": [
    "https://example.com/person.png"
  ],
  "resolution": "1080p"
}'
```
**图生视频{Image to video}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "gemini-omni-1.1-flash",
  "prompt": "让人物缓缓转头，看向窗外",
  "image_urls": [
    "https://example.com/person.png"
  ],
  "resolution": "1080p"
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**图生视频{Image to video}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "gemini-omni-1.1-flash",
  "prompt": "让人物缓缓转头，看向窗外",
  "image_urls": [
    "https://example.com/person.png"
  ],
  "resolution": "1080p"
}),
});
console.log(await res.json());
```
**200 图生视频{Image to video}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**首尾帧{First and last frame}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "gemini-omni-1.1-flash",
  "prompt": "画面从清晨过渡到黄昏",
  "first_frame_image": "https://example.com/morning.png",
  "last_frame_image": "https://example.com/dusk.png",
  "resolution": "1080p"
}'
```
**首尾帧{First and last frame}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "gemini-omni-1.1-flash",
  "prompt": "画面从清晨过渡到黄昏",
  "first_frame_image": "https://example.com/morning.png",
  "last_frame_image": "https://example.com/dusk.png",
  "resolution": "1080p"
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**首尾帧{First and last frame}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "gemini-omni-1.1-flash",
  "prompt": "画面从清晨过渡到黄昏",
  "first_frame_image": "https://example.com/morning.png",
  "last_frame_image": "https://example.com/dusk.png",
  "resolution": "1080p"
}),
});
console.log(await res.json());
```
**200 首尾帧{First and last frame}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**视频编辑{Video edit}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "gemini-omni-1.1-flash",
  "prompt": "把画面调成胶片质感的暖色调",
  "video_urls": [
    "https://example.com/source.mp4"
  ],
  "metadata": {
    "task": "edit"
  }
}'
```
**视频编辑{Video edit}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "gemini-omni-1.1-flash",
  "prompt": "把画面调成胶片质感的暖色调",
  "video_urls": [
    "https://example.com/source.mp4"
  ],
  "metadata": {
    "task": "edit"
  }
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**视频编辑{Video edit}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "gemini-omni-1.1-flash",
  "prompt": "把画面调成胶片质感的暖色调",
  "video_urls": [
    "https://example.com/source.mp4"
  ],
  "metadata": {
    "task": "edit"
  }
}),
});
console.log(await res.json());
```
**200 视频编辑{Video edit}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
**接续生成{Continue generation}::cURL**
```
curl --request POST \
  --url 'https://api.oairoute.com/v1/videos' \
  --header 'Authorization: Bearer YOUR_OAIRoute_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "model": "gemini-omni-1.1-flash",
  "prompt": "接着上一段继续向前推进，光线更暗一些",
  "extend_from_task_id": "task_01K8SGYNNVVBQTXNR4MM964S7K",
  "metadata": {
    "task": "extend"
  }
}'
```
**接续生成{Continue generation}::Python**
```
import requests
url = "https://api.oairoute.com/v1/videos"
headers = {
    "Authorization": "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
}
payload = {
  "model": "gemini-omni-1.1-flash",
  "prompt": "接着上一段继续向前推进，光线更暗一些",
  "extend_from_task_id": "task_01K8SGYNNVVBQTXNR4MM964S7K",
  "metadata": {
    "task": "extend"
  }
}
res = requests.post(url, headers=headers, json=payload)
print(res.json())
```
**接续生成{Continue generation}::JavaScript**
```
const res = await fetch("https://api.oairoute.com/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_OAIRoute_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "model": "gemini-omni-1.1-flash",
  "prompt": "接着上一段继续向前推进，光线更暗一些",
  "extend_from_task_id": "task_01K8SGYNNVVBQTXNR4MM964S7K",
  "metadata": {
    "task": "extend"
  }
}),
});
console.log(await res.json());
```
**200 接续生成{Continue generation}**
```
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01K8SGYNNNVBQTXNR4MM964S7K"
    }
  ]
}
```
