# 生成视频API文档

本文件介绍本平台视频生成接口的创建任务、查询结果、完成通知和视频下载，可交给 AI 编程助手完成接入。

## 接入前准备

- API 接入地址：`https://geekapi.net`，本文中的接口地址已按下载站点填写。
- 由平台签发的 API 令牌；请替换示例中的 `sk-你的令牌`。
- 当前可用的视频生成模型值；请替换示例中的 `video-model-id`。
- 如果使用完成通知，还需提供自己服务器上接收通知的公网 HTTPS 地址。

交给 AI 编程助手时，请它先阅读你的项目，再按本文完成创建任务、保存任务 ID、等待结果、失败提示和视频下载。缺少实际域名、令牌或模型值时应先向你确认，不要猜测，也不要把令牌写入源码、日志或公开网页。

视频生成采用异步任务模式。所有请求使用本平台令牌鉴权：

```http
Authorization: Bearer sk-你的令牌
```

## 线路 ID

同一个视频模型可能提供多条可用线路。线路 ID 是正整数，用于在创建任务时指定其中一条线路；它不是 `model` 值，也不是视频任务 ID。

可使用同一个平台令牌查询指定模型当前公开且可用的线路：

```bash
curl "https://geekapi.net/api/platform/model-lines?model=video-model-id" \
  -H "Authorization: Bearer sk-你的令牌"
```

响应中 `data.items[].id` 就是创建视频任务时可使用的线路 ID：

```json
{
    "success": true,
    "data": {
        "auto_switch_enabled": true,
        "current_id": 0,
        "items": [
            {
                "id": 12,
                "name": "线路 1"
            }
        ]
    }
}
```

创建任务时，可在 JSON 请求体中传入要使用的线路 ID：

```json
{"lineId": 12}
```

- 不传 `lineId` 时，平台按该模型当前的线路策略自动选择。
- 传入当前模型的可用线路 ID 时，本次任务固定使用该线路，不再在其他线路之间自动切换。
- 非正整数会返回 `400` 错误；线路已停用、已删除或不属于当前模型时返回 `503` 错误，不会改用其他线路。

## 创建视频任务

```http
POST /v1/videos
Content-Type: application/json
```

### 请求字段

| 字段              | 类型             | 必填       | 说明                                            |
| ----------------- | ---------------- | ---------- | ----------------------------------------------- |
| `model`           | string           | 是         | 本平台视频模型值。                              |
| `lineId`          | number           | 否         | 指定线路 ID，必须是正整数。                     |
| `prompt`          | string           | 视模式而定 | 视频提示词；纯参考素材模式下可选。              |
| `generationType`  | string           | 否         | 生成类型，默认 `auto`。                         |
| `imageUrl`        | string           | 否         | 单张参考图 URL。                                |
| `imageUrls`       | string[]         | 否         | 多张参考图 URL。                                |
| `firstFrameUrl`   | string           | 否         | 首帧图片 URL；使用首尾帧模式时必填。            |
| `lastFrameUrl`    | string           | 否         | 尾帧图片 URL；必须与 `firstFrameUrl` 一起传入。 |
| `videoUrls`       | string[]         | 否         | 参考视频 URL 列表。                             |
| `videoDurations`  | number[]         | 视素材而定 | 参考视频时长（秒），与 `videoUrls` 逐项对应；Seedance 视频素材 ID 必填。 |
| `audioUrls`       | string[]         | 否         | 参考音频 URL 列表。                             |
| `audioDurations`  | number[]         | 视素材而定 | 参考音频时长（秒），与 `audioUrls` 逐项对应；Seedance 音频素材 ID 必填。 |
| `aspectRatio`     | string           | 否         | 画面比例，如 `16:9`、`9:16`、`1:1`。            |
| `seconds`         | string 或 number | 否         | 视频时长（秒）；可用值以所选模型为准。          |
| `resolution`      | string           | 否         | 输出清晰度，如 `720p`、`1080p`。                |
| `videoQualityMode` | string          | 否         | 画质模式：`native` 原生画质，`enhanced` 画质增强；不传时使用所选线路默认值。 |
| `generateAudio`   | boolean          | 否         | 是否生成音频，默认 `true`；传 `false` 关闭。     |
| `negativePrompt`  | string           | 否         | 反向提示词。                                    |
| `seed`            | number           | 否         | 随机种子。                                      |
| `callbackUrl`     | string           | 否         | 你服务器上的通知接收地址，必须是公网 HTTPS；任务完成或失败时，平台会通知这个地址。 |

**字段支持范围**

不同模型支持的模式、参考素材类型、时长和分辨率可能不同。请求中只需使用本文列出的统一字段。

### Seedance 参考素材时长

| 模型 | 单个参考视频 | 单个参考音频 | 视频总时长 | 音频总时长 |
| --- | --- | --- | --- | --- |
| `seedance-2.0` | 2–15 秒 | 2–15 秒 | 不超过 15 秒 | 不超过 15 秒 |
| `seedance-2.5` | 2–30 秒；`edit-video` 为 4–30 秒 | 2–30 秒 | 不超过 30 秒 | 不超过 30 秒 |

上下界均包含在允许范围内，视频和音频分别累计。URL 素材由平台读取实际时长；超限或无法确认时长时，在提交生成和扣费前返回 `400`。使用 `asset://` 视频或音频素材 ID 时，必须提供对应的 `videoDurations` 或 `audioDurations`，数组长度与同类素材数量一致，可使用小数秒。

### generationType 取值

| 值                   | 说明                                               |
| -------------------- | -------------------------------------------------- |
| `auto`               | 根据请求中提供的文本和参考素材生成视频。           |
| `text-to-video`      | 文生视频。                                         |
| `image-to-video`     | 单图图生视频。                                     |
| `reference-to-video` | 使用一项或多项参考图、参考视频或参考音频生成视频。 |
| `start-end-to-video` | 使用首帧和尾帧生成视频。                           |
| `edit-video`         | 使用一个参考视频和提示词编辑视频。                 |
| `video-extension`    | 使用参考视频和提示词向前或向后延长视频。           |

### videoQualityMode 取值

`videoQualityMode` 适用于支持双画质的线路：`native` 为原生画质，`enhanced` 为画质增强。`resolution` 表示最终输出分辨率。480p 同样可选两种画质，按对应档位计价；不支持双画质的线路传入该字段会返回参数错误。

需要原生画质时，请明确传入 `"videoQualityMode": "native"`；省略该字段会沿用线路默认画质，默认值可能是增强模式。

### 请求示例

以下示例假设所选线路支持双画质。

```bash
curl https://geekapi.net/v1/videos \
  -H "Authorization: Bearer sk-你的令牌" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "video-model-id",
    "lineId": 12,
    "generationType": "text-to-video",
    "prompt": "黄昏海边，一架纸飞机从镜头前飞过",
    "aspectRatio": "16:9",
    "seconds": 5,
    "resolution": "720p",
    "videoQualityMode": "native",
    "generateAudio": true,
    "negativePrompt": "模糊、闪烁",
    "callbackUrl": "https://example.com/video-callback"
  }'
```

创建成功后返回视频任务对象：

```json
{
    "id": "task_xxx",
    "object": "video",
    "model": "video-model-id",
    "status": "queued",
    "progress": 0,
    "created_at": 1782658000
}
```

`callbackUrl` 也适用于 `POST /v1/video/generations` 和 `POST /v1/videos/{video_id}/remix`，JSON 与 multipart 请求均可传入。未传时只需按下文的查询接口获取结果。

## 任务完成通知（可选）

视频处理需要时间。创建任务后，你会先拿到任务 ID，稍后才能获取结果。你可以定时查询，也可以让平台在处理结束时主动通知你的服务器，这就是“回调”。

**没有自己的服务器时，不需要填写 `callbackUrl`，按下文每 60 秒查询一次即可。**

### 设置通知接收地址

如果你有自己的服务器，在创建任务的请求中加入：

```json
{
    "callbackUrl": "https://your-service.example/video-callback"
}
```

将示例地址换成你服务器上用来接收通知的接口。这个接口需要能从公网访问，并使用 HTTPS。

### 你会收到什么

处理成功或失败后，平台会向这个地址发送一份 JSON 通知。下面是成功通知的示例，只展示关键字段：

```http
POST /video-callback HTTP/1.1
Host: your-service.example
Content-Type: application/json
X-Video-Event-Id: video:task_xxx:SUCCESS

{
    "id": "task_xxx",
    "status": "completed",
    "url": "https://example.com/result.mp4"
}
```

| 字段 | 怎么看 |
| --- | --- |
| `id` | 对应你创建的哪一个任务。 |
| `status` | `completed` 表示成功，`failed` 表示失败。 |
| `url` | 成功后的视频地址。 |
| `error.message` | 失败原因，任务失败时查看。 |

失败通知中的关键字段如下：

```json
{
    "id": "task_xxx",
    "status": "failed",
    "error": {
        "message": "视频处理失败"
    }
}
```

通知中的字段与查询任务时返回的字段相同，可以用同一套方式读取结果。

### 收到通知后怎么处理

1. 你的接收接口尽快返回 HTTP `200` 或 `204`，表示“已收到”；其他 `2xx` 状态码也可以。耗时处理放到后台执行。
2. 检查通知中的 `id` 是否属于你创建的任务，再用自己的平台令牌调用 `GET /v1/videos/{task_id}` 确认结果。通知本身不带签名或密钥，确认后再更新业务状态或展示视频。
3. 同一条通知可能重复收到。`X-Video-Event-Id` 是通知编号，重复发送时保持相同；你的服务器应记住已处理的编号，避免重复处理。

如果平台没有成功送达通知，最多会尝试发送 5 次。因此，使用通知时仍建议每 60 秒查询一次，以免漏掉结果。接收地址应直接处理请求，平台不会跟随地址重定向。创建任务时未填写 `callbackUrl`，该任务就不会收到完成通知。

## 查询视频任务

```http
GET /v1/videos/{task_id}
```

任务状态包括 `queued`、`in_progress`、`completed` 和 `failed`。任务完成后，响应中会包含视频结果：

```json
{
    "id": "task_xxx",
    "object": "video",
    "model": "video-model-id",
    "status": "completed",
    "progress": 100,
    "created_at": 1782658000,
    "completed_at": 1782658060,
    "url": "https://example.com/result.mp4",
    "metadata": {
        "url": "https://example.com/result.mp4",
        "video_url": "https://example.com/result.mp4",
        "videos": [
            {
                "url": "https://example.com/result.mp4"
            }
        ]
    }
}
```

`url` 是最终视频地址，并保留在 `metadata.url` / `metadata.video_url` 中。完成通知使用相同字段。

有自己的服务器时，收到完成通知后立即查询，并每 60 秒查询一次，以免漏掉结果。只有客户端时，每 60 秒查询一次；应用重新进入前台或网络恢复后可立即查询一次。成功（`completed`）或失败（`failed`）后停止查询。提高查询频率不会加快任务完成，请遵循上述间隔。任务完成后请及时保存结果。

## 获取视频内容

任务完成后可通过以下接口读取视频内容：

```http
GET /v1/videos/{task_id}/content
```

该接口会传输视频文件，请在确认任务完成后调用，不要用它轮询任务状态。

## 网络与失败处理

- 保存创建任务时返回的 `id`，方便刷新页面或重启应用后继续查询。
- HTTP 超时、网络错误、`429` 或 `5xx` 表示本次请求没有成功，不等于任务失败。查询失败时稍后重试，避免重新创建同一任务。
- 查询返回 `failed` 时显示 `error.message`。`unknown` 表示状态暂时无法确定，应保留任务 ID，稍后再次查询。
- 接入完成后，用成功任务、失败任务和网络中断验证状态恢复；使用完成通知时，还需验证重复通知不会重复处理。
