> ## Documentation Index
> Fetch the complete documentation index at: https://omnirelay.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 视频生成

> 通过异步任务接口用文字生成视频，按实际生成的输出 tokens 计费。

视频生成需要几分钟，因此以**任务**方式运行：提交任务后立即拿到任务 ID，然后查询任务直到完成。接口与兼容 Seedance 的 SDK 使用的任务接口一致：

* `POST https://api.omnirelay.ai/api/v3/contents/generations/tasks` 提交任务。
* `GET https://api.omnirelay.ai/api/v3/contents/generations/tasks/{id}` 查询任务。

请用 OmniRelay API Key 作为 Bearer token。Key 的规则与文本模型相同：有效期、[IP 白名单](https://omnirelay.ai/docs/cn/overview/rate-limits.md#key-的-ip-白名单)、[模型限制](https://omnirelay.ai/docs/cn/overview/authentication.md#限定-key-可调用的模型)、预算以及[速率与并发限制](https://omnirelay.ai/docs/cn/overview/rate-limits.md)。运行中的任务计为一个进行中的调用。你也可以先在控制台的模型体验中试用视频模型。

## 模型

| 模型 ID | 输入 | 分辨率 | 时长 |
| - | - | - | - |
| `doubao-seedance-2-0-260128` | 文字描述 | `480p`、`720p` | 4–10 秒 |

视频模型会出现在你自己的 [`GET /v1/models`](https://omnirelay.ai/docs/cn/llms/listing-models#视频模型) 列表中，带有 `type: "video"` 以及你所在工作区的价格。

## 价格

视频按**实际生成的输出 tokens** 计费，标价为**每百万输出 tokens USD 25**。tokens 数由画面尺寸和时长决定：

```
输出 tokens = 宽 × 高 × (24 × 秒数 + 1) / 1024
```

一段 5 秒、480p、16:9（864 × 496）的视频是 50,638 tokens，约 **USD 1.27**。10 秒 720p 视频按画面比例不同约 USD 5.2–5.7。你的折扣与文本模型一样生效。

提交时，OmniRelay 会按所选分辨率下最大画面和时长再加 10% 预留费用。任务成功后按实际生成的 tokens 扣费，预留的剩余部分退回余额。\*\*失败、过期或取消的任务不收费。\*\*任务结果中的 `cost_microusd` 是本次费用。详见[用量与计费](https://omnirelay.ai/docs/cn/general/usage-billing.md#视频模型)。

## 提交任务

```bash cURL theme={null}
curl https://api.omnirelay.ai/api/v3/contents/generations/tasks \
  -H "Authorization: Bearer $OMNIRELAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "doubao-seedance-2-0-260128",
    "content": [{"type": "text", "text": "日出时一只纸船漂在平静的池塘上，镜头缓慢平移"}],
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 5
  }'
```

```python Python theme={null}
import os, time, requests

BASE = "https://api.omnirelay.ai/api/v3/contents/generations/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['OMNIRELAY_API_KEY']}"}

task = requests.post(BASE, headers=HEADERS, json={
    "model": "doubao-seedance-2-0-260128",
    "content": [{"type": "text", "text": "日出时一只纸船漂在平静的池塘上，镜头缓慢平移"}],
    "resolution": "480p",
    "ratio": "16:9",
    "duration": 5,
}).json()

while True:
    result = requests.get(f"{BASE}/{task['id']}", headers=HEADERS).json()
    if result["status"] in ("succeeded", "failed", "expired", "cancelled"):
        break
    time.sleep(5)

print(result["status"], result.get("content", {}).get("video_url"))
```

```javascript JavaScript theme={null}
const BASE = "https://api.omnirelay.ai/api/v3/contents/generations/tasks";
const headers = { Authorization: `Bearer ${process.env.OMNIRELAY_API_KEY}`, "Content-Type": "application/json" };

const task = await (await fetch(BASE, {
  method: "POST",
  headers,
  body: JSON.stringify({
    model: "doubao-seedance-2-0-260128",
    content: [{ type: "text", text: "日出时一只纸船漂在平静的池塘上，镜头缓慢平移" }],
    resolution: "480p",
    ratio: "16:9",
    duration: 5,
  }),
})).json();

let result;
do {
  await new Promise((resolve) => setTimeout(resolve, 5000));
  result = await (await fetch(`${BASE}/${task.id}`, { headers })).json();
} while (!["succeeded", "failed", "expired", "cancelled"].includes(result.status));

console.log(result.status, result.content?.video_url);
```

提交成功返回 `{"id": "<任务 ID>"}`。请保存这个 ID，它同时也是用量日志里的请求 ID。

## 参数

只接受下列字段，其他字段一律返回 `400 invalid_parameter`，因为每个接受的字段都可能影响价格。

| 字段 | 必填 | 取值 |
| - | - | - |
| `model` | 是 | 视频模型 ID |
| `content` | 是 | 恰好一项 `{"type": "text", "text": "..."}`，1–4000 个字符 |
| `resolution` | 否 | `480p`（默认）或 `720p` |
| `ratio` | 否 | `16:9`（默认）、`4:3`、`1:1`、`3:4`、`9:16`、`21:9`、`adaptive` |
| `duration` | 否 | 整数秒，4–10（默认 5） |
| `seed` | 否 | 整数，−1 到 4294967295 |
| `generate_audio` | 否 | 布尔值；除非设为 `false`，视频带音轨 |
| `watermark`、`camera_fixed` | 否 | 布尔值 |

暂不支持图生视频（首帧或尾帧）。

## 查询任务

`GET /api/v3/contents/generations/tasks/{id}` 返回任务。只有创建任务的用户可以查询；其他 ID 一律返回 `404`。

```json theme={null}
{
  "id": "3f0c9a2e-6b1d-4c35-9a7e-2d8c5b1e4f60",
  "model": "doubao-seedance-2-0-260128",
  "status": "succeeded",
  "created_at": 1791994620,
  "updated_at": 1791994785,
  "content": { "video_url": "https://…/video.mp4?…" },
  "duration": 5,
  "ratio": "16:9",
  "resolution": "480p",
  "framespersecond": 24,
  "seed": 9846,
  "generate_audio": true,
  "usage": { "completion_tokens": 50638, "total_tokens": 50638 },
  "cost_microusd": 1265950
}
```

| `status` | 含义 |
| - | - |
| `queued`、`running` | 仍在生成。几秒后再查询；大多数任务在 2–4 分钟内完成。 |
| `succeeded` | 已完成。`content.video_url` 是 MP4 链接，`cost_microusd` 是本次费用。 |
| `failed` | 未生成，例如被内容审核拦截。`error.code` 和 `error.message` 说明原因。不收费。 |
| `expired`、`cancelled` | 未生成。不收费。 |

> [!WARNING]
>
> `content.video_url` 是签名链接，**在视频生成后 48 小时失效**。如需保留请自行下载；OmniRelay 不保存副本。

计费不依赖你查询：即使没有人查询任务，任务完成后 OmniRelay 也会自动结算。

## 失败与扣费

| 情况 | 响应 | 扣费 |
| - | - | - |
| 字段或取值不合法 | `400`，带 `error.param` | 不扣费，未发送 |
| 余额、Key 预算或成员预算不足以预留 | `402` | 不扣费，未发送 |
| 进行中的调用或每分钟调用过多 | `429` | 不扣费 |
| 提交时无法确认任务（超时、连接中断、服务商错误） | `502`/`504`，`video_submit_held` | 转入人工核对；只有确实生成了才扣费 |
| 任务最终 `failed`、`expired` 或 `cancelled` | `200`，带该状态 | 不扣费，预留全额退回 |

被挂起的任务在重新提交前请先带上任务 ID 联系客服，避免同一段视频付两次费。

## 限制

* 仅支持文生视频，每个任务一段文字描述。
* 分辨率最高 720p，时长最长 10 秒。
* 请求体不超过 64 KiB。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.