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

# 视频生成：Seedance 2.0

> 用 Seedance 2.0 文生 / 图生 / 首尾帧 / 参考视频，输出自带同步音频 —— OpenAI 兼容异步接口，curl / Python 上手

Seedance 2.0（字节跳动）是一款多模态视频生成模型，支持**文生视频、图生视频、首尾帧、参考视频**四种输入，且**输出默认自带同步音频**。RuAPI 提供 **OpenAI 兼容的异步视频接口**：提交任务 → 轮询状态 → 下载视频。USDT 计费，无需外币卡。

<Tip>
  **默认带声音** —— Seedance 2.0 生成的视频自带同步音频（对白 / 环境音 / 音效），无需任何额外参数。
</Tip>

<Warning>
  **视频结果仅保留 7 天**，生成后请尽快下载保存；过期后链接将无法访问。
</Warning>

## 可用模型

| 模型 ID                      | 说明          |
| -------------------------- | ----------- |
| `doubao-seedance-2.0-fast` | 更快、更便宜，日常首选 |
| `doubao-seedance-2.0`      | 画质更高的完整版    |

准确的价格见主站 **[价格页面](https://www.ruapi.ai/pricing)**（视频按 token 计费）。

## 接口地址与鉴权

* **Base URL**：`https://www.ruapi.ai/v1`
* **鉴权**：请求头带 `Authorization: Bearer sk-你的KEY`（在控制台「令牌」页创建）

视频是**异步**的，一共三步：

<Steps>
  <Step title="提交任务">
    `POST /v1/videos` → 返回任务 `id`
  </Step>

  <Step title="轮询状态">
    `GET /v1/videos/{id}` → 直到 `status` 变成 `completed`
  </Step>

  <Step title="下载视频">
    `GET /v1/videos/{id}/content` → 拿到 MP4
  </Step>
</Steps>

## 第 1 步：提交任务（文生视频）

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "doubao-seedance-2.0-fast",
      "prompt": "城市夜景，霓虹灯反射在湿漉漉的街道上，赛博朋克风格，镜头缓慢推进",
      "seconds": "5",
      "metadata": { "resolution": "720p", "ratio": "16:9" }
    }'
  ```

  ```python Python (requests) theme={null}
  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/videos",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "doubao-seedance-2.0-fast",
          "prompt": "城市夜景，霓虹灯反射在湿漉漉的街道上，赛博朋克风格，镜头缓慢推进",
          "seconds": "5",
          "metadata": {"resolution": "720p", "ratio": "16:9"},
      },
  )
  task_id = resp.json()["id"]
  print("任务已提交:", task_id)
  ```

  ```javascript Node.js (fetch) theme={null}
  const resp = await fetch("https://www.ruapi.ai/v1/videos", {
    method: "POST",
    headers: {
      Authorization: "Bearer sk-你的KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "doubao-seedance-2.0-fast",
      prompt: "城市夜景，霓虹灯反射在湿漉漉的街道上，赛博朋克风格，镜头缓慢推进",
      seconds: "5",
      metadata: { resolution: "720p", ratio: "16:9" },
    }),
  });
  const { id } = await resp.json();
  console.log("任务已提交:", id);
  ```
</CodeGroup>

返回体（`id` 就是任务号，后面两步都用它）：

```json theme={null}
{
  "id": "task_guXmm9BZpLpYaxfky7mkR2kSlRtgDSe9",
  "object": "video",
  "model": "doubao-seedance-2.0-fast",
  "status": "queued",
  "progress": 0,
  "created_at": 1783579686
}
```

## 第 2 步：轮询状态

用**复数**路由 `GET /v1/videos/{id}` 查询，每 5 秒左右查一次。`status` 会经历 `queued → in_progress → completed`。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos/task_你的任务ID \
    -H "Authorization: Bearer sk-你的KEY"
  ```

  ```python Python (requests) theme={null}
  import requests

  r = requests.get(
      f"https://www.ruapi.ai/v1/videos/{task_id}",
      headers={"Authorization": "Bearer sk-你的KEY"},
  ).json()
  print(r["status"], r.get("progress"))
  ```
</CodeGroup>

完成后返回（`metadata.url` 即下载地址）：

```json theme={null}
{
  "id": "task_guXmm9BZpLpYaxfky7mkR2kSlRtgDSe9",
  "object": "video",
  "status": "completed",
  "progress": 100,
  "metadata": {
    "url": "https://www.ruapi.ai/v1/videos/task_guXmm9BZpLpYaxfky7mkR2kSlRtgDSe9/content"
  }
}
```

## 第 3 步：下载视频

<CodeGroup>
  ```bash curl theme={null}
  curl -L https://www.ruapi.ai/v1/videos/task_你的任务ID/content \
    -H "Authorization: Bearer sk-你的KEY" \
    -o seedance.mp4
  ```

  ```python Python (requests) theme={null}
  video = requests.get(
      f"https://www.ruapi.ai/v1/videos/{task_id}/content",
      headers={"Authorization": "Bearer sk-你的KEY"},
  )
  with open("seedance.mp4", "wb") as f:
      f.write(video.content)
  print("已保存 seedance.mp4")
  ```
</CodeGroup>

## 完整示例：一段脚本跑通全流程

复制即用，把 `sk-你的KEY` 换成自己的 key：

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

BASE = "https://www.ruapi.ai/v1"
HEADERS = {"Authorization": "Bearer sk-你的KEY"}

# 1) 提交任务
resp = requests.post(
    f"{BASE}/videos",
    headers=HEADERS,
    json={
        "model": "doubao-seedance-2.0-fast",
        "prompt": "城市夜景，霓虹灯反射在湿漉漉的街道上，赛博朋克风格，镜头缓慢推进",
        "seconds": "5",
        "metadata": {"resolution": "720p", "ratio": "16:9"},
    },
)
resp.raise_for_status()
task_id = resp.json()["id"]
print("任务已提交:", task_id)

# 2) 轮询直到完成（视频通常需要 1-3 分钟）
while True:
    r = requests.get(f"{BASE}/videos/{task_id}", headers=HEADERS).json()
    print("状态:", r.get("status"), r.get("progress"))
    if r.get("status") == "completed":
        break
    if r.get("status") == "failed":
        raise RuntimeError(f"生成失败: {r.get('error')}")
    time.sleep(5)

# 3) 下载（结果仅保留 7 天，尽快保存）
video = requests.get(f"{BASE}/videos/{task_id}/content", headers=HEADERS)
with open("seedance.mp4", "wb") as f:
    f.write(video.content)
print("已保存 seedance.mp4")
```

## 参数说明

顶层字段：

| 字段         | 类型     | 说明                                                 |
| ---------- | ------ | -------------------------------------------------- |
| `model`    | string | `doubao-seedance-2.0-fast` 或 `doubao-seedance-2.0` |
| `prompt`   | string | **必填**，画面的文字描述                                     |
| `seconds`  | string | 时长（秒），支持 **4–15 秒**，如 `"5"`、`"10"`                 |
| `metadata` | object | 分辨率、比例、图片/视频输入等，见下表                                |

`metadata` 内字段：

| 字段           | 类型        | 说明                                                                     |
| ------------ | --------- | ---------------------------------------------------------------------- |
| `resolution` | string    | `"480p"` / `"720p"` / `"1080p"`                                        |
| `ratio`      | string    | 画面比例，如 `"16:9"`、`"9:16"`、`"1:1"`                                       |
| `input_type` | string    | 输入类型（一般可省略，系统会自动推断）：`text_to_video` / `first_last_frame` / `reference` |
| `images`     | string\[] | 图片 URL 数组（图生视频用）                                                       |
| `videos`     | string\[] | 视频 URL 数组（参考视频用）                                                       |

<Note>
  分辨率越高、时长越长，消耗的 token 越多、越贵。不确定就先用 `480p` / `5` 秒跑通再调。
</Note>

## 四种输入模式

`input_type` 通常**不用手填**，系统按你给的图片 / 视频数量自动推断；也可用 `metadata.input_type` 显式指定。

| 模式   | 怎么给输入                         | 推断出的 `input_type`  |
| ---- | ----------------------------- | ------------------ |
| 文生视频 | 只给 `prompt`                   | `text_to_video`    |
| 图生视频 | `metadata.images` 传 **1 张**图  | `reference`        |
| 首尾帧  | `metadata.images` 传 **2 张**图  | `first_last_frame` |
| 参考视频 | `metadata.videos` 传 **1 个**视频 | `reference`        |

<Note>
  图片 / 视频必须是**公网可访问的 URL**（上游要去拉取）；图片支持 **JPG / PNG / WebP**，视频支持 **MP4**。**不支持 base64 内联**（上游会因请求体过大而失败）。
</Note>

下面每种模式**只展示第 1 步「提交」**；第 2 步轮询、第 3 步下载对所有模式都完全一样。

### 模式一：文生视频

只给文字 `prompt`，纯靠描述生成。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "doubao-seedance-2.0-fast",
      "prompt": "城市夜景，霓虹灯反射在湿漉漉的街道上，赛博朋克风格，镜头缓慢推进",
      "seconds": "5",
      "metadata": { "resolution": "720p", "ratio": "16:9" }
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/videos",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "doubao-seedance-2.0-fast",
          "prompt": "城市夜景，霓虹灯反射在湿漉漉的街道上，赛博朋克风格，镜头缓慢推进",
          "seconds": "5",
          "metadata": {"resolution": "720p", "ratio": "16:9"},
      },
  )
  print(resp.json()["id"])  # 拿到 task id，再按上文完整脚本轮询、下载
  ```
</CodeGroup>

### 模式二：图生视频（1 张图）

`metadata.images` 传 **1 张**图的 URL，以它作参考生成动态视频。`prompt` 描述你想要的动作 / 运镜。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "doubao-seedance-2.0-fast",
      "prompt": "让画面里的人物微笑并自然地挥手，镜头缓慢推进",
      "seconds": "5",
      "metadata": {
        "resolution": "720p",
        "ratio": "16:9",
        "images": ["https://你的域名/portrait.jpg"]
      }
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/videos",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "doubao-seedance-2.0-fast",
          "prompt": "让画面里的人物微笑并自然地挥手，镜头缓慢推进",
          "seconds": "5",
          "metadata": {
              "resolution": "720p",
              "ratio": "16:9",
              "images": ["https://你的域名/portrait.jpg"],
          },
      },
  )
  print(resp.json()["id"])
  ```
</CodeGroup>

### 模式三：首尾帧（2 张图）

`metadata.images` 传 **2 张**图：**第 1 张 = 首帧，第 2 张 = 尾帧**，生成从首帧平滑过渡到尾帧的视频。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "doubao-seedance-2.0-fast",
      "prompt": "从第一张画面平滑过渡到第二张，镜头运动自然，电影感",
      "seconds": "5",
      "metadata": {
        "resolution": "720p",
        "ratio": "16:9",
        "images": [
          "https://你的域名/first.jpg",
          "https://你的域名/last.jpg"
        ]
      }
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/videos",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "doubao-seedance-2.0-fast",
          "prompt": "从第一张画面平滑过渡到第二张，镜头运动自然，电影感",
          "seconds": "5",
          "metadata": {
              "resolution": "720p",
              "ratio": "16:9",
              "images": [
                  "https://你的域名/first.jpg",
                  "https://你的域名/last.jpg",
              ],
          },
      },
  )
  print(resp.json()["id"])
  ```
</CodeGroup>

### 模式四：参考视频（1 个视频）

`metadata.videos` 传 **1 个**短视频的 URL，参考它的**主体动作**重新演绎（如换风格、换场景）。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "doubao-seedance-2.0-fast",
      "prompt": "保持视频里人物的动作，画面改成赛博朋克霓虹街区风格",
      "seconds": "5",
      "metadata": {
        "resolution": "480p",
        "ratio": "9:16",
        "videos": ["https://你的域名/dance.mp4"]
      }
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/videos",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "doubao-seedance-2.0-fast",
          "prompt": "保持视频里人物的动作，画面改成赛博朋克霓虹街区风格",
          "seconds": "5",
          "metadata": {
              "resolution": "480p",
              "ratio": "9:16",
              "videos": ["https://你的域名/dance.mp4"],
          },
      },
  )
  print(resp.json()["id"])
  ```
</CodeGroup>

<Warning>
  **参考视频对输入要求较高**：请用\*\*时长 ≤ 15 秒、画面有清晰主体（如人物）\*\*的短视频；卡通、无明显主体或过长的视频容易生成失败。建议参考视频的画面比例与目标 `ratio` 一致（如竖屏源配 `9:16`）。
</Warning>

### 进阶：多图 / 多视频参照

`images` 和 `videos` 都是**数组**，可以一次传多个做联合参照（均已实测通过）：

* **多图参照**：`images` 传 **3 张及以上**（官方最多 9 张），综合多张图的主体 / 场景 / 风格生成。传 3 张以上时系统自动判为 `reference`，无需手填 `input_type`。
* **多视频参照**：`videos` 传 **2 个及以上**（官方最多 3 个，多段视频**合计时长 ≤ 15 秒**），参考多段动作合成。

<CodeGroup>
  ```bash curl theme={null}
  curl https://www.ruapi.ai/v1/videos \
    -H "Authorization: Bearer sk-你的KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "doubao-seedance-2.0-fast",
      "prompt": "综合这几张图的主体和风格，生成一段连贯的视频，镜头自然运动",
      "seconds": "5",
      "metadata": {
        "resolution": "720p",
        "ratio": "16:9",
        "images": [
          "https://你的域名/ref1.jpg",
          "https://你的域名/ref2.jpg",
          "https://你的域名/ref3.jpg"
        ]
      }
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://www.ruapi.ai/v1/videos",
      headers={"Authorization": "Bearer sk-你的KEY"},
      json={
          "model": "doubao-seedance-2.0-fast",
          "prompt": "综合这几张图的主体和风格，生成一段连贯的视频，镜头自然运动",
          "seconds": "5",
          "metadata": {
              "resolution": "720p",
              "ratio": "16:9",
              "images": [
                  "https://你的域名/ref1.jpg",
                  "https://你的域名/ref2.jpg",
                  "https://你的域名/ref3.jpg",
              ],
          },
      },
  )
  print(resp.json()["id"])
  ```
</CodeGroup>

<Note>
  多视频同理：把 `images` 换成 `videos`、传多个短视频 URL 即可（每个建议 ≤ 7 秒、有清晰主体，合计 ≤ 15 秒）。
</Note>

## 任务状态

| `status`      | 含义                      |
| ------------- | ----------------------- |
| `queued`      | 排队中                     |
| `in_progress` | 生成中                     |
| `completed`   | 完成，`metadata.url` 为下载地址 |
| `failed`      | 失败，`error` 字段说明原因       |

## 计费

视频按 **token 计费**（分辨率 × 时长）。提交时会**预扣**一笔押金，任务完成后按实际用量**多退少不补**，最终以扣费为准。价格见 **[价格页面](https://www.ruapi.ai/pricing)**。

## 常见问题

<AccordionGroup>
  <Accordion title="报 model_not_found / 404">
    检查两点：`model` 名是否写对（`doubao-seedance-2.0-fast`）；地址是否是 `https://www.ruapi.ai/v1/videos`（带 `/v1`）。
  </Accordion>

  <Accordion title="一直是 queued / in_progress">
    正常现象。视频生成通常要 **1-3 分钟**，耐心轮询即可，别把间隔设太短。
  </Accordion>

  <Accordion title="下载的文件是空的 / 打不开">
    很可能已**超过 7 天**，上游链接过期。请在生成后尽快下载保存。
  </Accordion>

  <Accordion title="参考视频任务 failed">
    参考视频对输入要求高。请确认参考视频**时长 ≤ 15 秒、画面有清晰主体**、且是可公网访问的 MP4；卡通或无明显主体的视频常会失败。
  </Accordion>

  <Accordion title="查询任务用哪个地址？">
    用**复数** `GET /v1/videos/{id}`。这是 OpenAI 兼容格式，返回里 `metadata.url` 直接就是下载地址。
  </Accordion>
</AccordionGroup>

## 接下来

* [价格与计费规则](/zh/pricing)
* 有问题？[support@ruapi.ai](mailto:support@ruapi.ai)
