# 数字人 / 剪辑 API

> 形象库 + 数字人出片 + 对口型 + 动作迁移 + 网感剪辑,全部走同一把 sk-gpushare-* Key

来源：https://qianduan.dflop.top/docs/reference/digital-human-apis

用一张照片或一段视频注册一个**可复用的数字人形象**,再用音频或文字驱动它出片;也可以给现成视频做对口型、或把一段视频的动作迁移到人物图上;还可以把一段口播视频交给[网感剪辑](#五、网感剪辑-clip-compose),自动配上字幕特效、标题、模板包装和背景音乐。

鉴权与其它端点完全一致 —— 同一把 `sk-gpushare-*` Key,四种方式任选(`x-api-key` / `x-goog-api-key` header / `?key=` query / `Authorization: Bearer`),详见 [鉴权](./authentication.md)。计费扣账户余额(全部 Key 共享),余额不足返回 **402** `quota_exceeded`。

| 端点 | 用途 | 计费 |
|---|---|---|
| `POST /v1/videos/avatars` | 注册数字人形象(异步) | **按次** |
| `GET /v1/videos/avatars` | 我的形象库 | 免费 |
| `GET /v1/videos/avatars/{id}` | 查询形象创建状态 | 免费 |
| `DELETE /v1/videos/avatars/{id}` | 删除形象 | 免费 |
| `GET /v1/videos/avatars/presets` | 平台预置形象 | 免费 |
| `POST /v1/videos/generations` | 出片(数字人 / 对口型 / 动作迁移 **按秒**;网感剪辑 **按次**) | **按秒 / 按次** |
| `GET /v1/videos/generations/{id}` | 查询出片任务状态 | 免费 |
| `GET /v1/videos/clip-templates` | 网感剪辑模板列表(分页) | 免费 |
| `GET /v1/videos/clip-templates/categories` | 网感剪辑模板分类 | 免费 |
| `POST /v1/videos/clip-subtitles` | 网感剪辑字幕解析(同步) | **按次**(当前 0) |

出片与查询用的是 [媒体 API](./media-apis.md) 里那对通用的视频端点,只是换了 `model` 和请求体字段 —— 下面每种玩法都给了完整示例。

---

## 一、形象库

### POST /v1/videos/avatars

用一张正面照片(或一段人物视频)注册形象。**异步**:立刻返回一个 `pending` 记录,轮询到 `ready` 后才能用来出片。上游通常 5–10 分钟。

```json
{
  "name": "我的主播",
  "source_url": "https://example.com/portrait.jpg",
  "source_kind": "image"
}
```

| 字段 | 必填 | 说明 |
|---|---|---|
| `name` | 是 | 1–20 字符,形象在库里的名字 |
| `source_url` | 是 | **公网可访问**的 http(s) 直链。素材由上游拉取,本平台不提供上传端点 —— 请自行托管(对象存储 / CDN / 任意公网直链均可) |
| `source_kind` | 否 | `image`(默认)或 `video` |

响应:

```json
{
  "id": "9f1c…",
  "name": "我的主播",
  "source_kind": "image",
  "status": "pending",
  "error": null,
  "created_at": "2026-07-29T08:12:00+00:00"
}
```

**这个 `id` 就是你之后要用的形象引用** —— 出片时把它填进 `avatar` 字段即可,不需要关心底层的形象编号。

### GET /v1/videos/avatars/{id}

轮询创建状态,建议 15–30 秒一次。

```json
{ "id": "9f1c…", "name": "我的主播", "status": "ready", "error": null, "created_at": "…" }
```

`status` 三态:`pending` / `ready` / `failed`。**失败会自动全额退款**(退款以这条记录为凭据,所以 `pending` 期间不允许删除)。

### GET /v1/videos/avatars

列出本账号的形象(最多 200 条,按创建时间倒序)。

### DELETE /v1/videos/avatars/{id}

删除一个形象。创建中(`pending`)的形象不能删 —— 等它成功或失败后再删。

### GET /v1/videos/avatars/presets

平台预置形象,**免费直接用**,不必自己注册:

```json
{ "avatars": [ { "id": "…", "name": "职业女主播" }, … ] }
```

把 `presets` 里的 `id` 直接填进出片请求的 `avatar` 字段即可。

---

## 二、数字人出片(`dh-avatar`)

驱动一个已就绪的形象说话。成片长度**由驱动音频 / 文案决定**,按成片秒数计费。

### 方式 1:用音频驱动

```json
{
  "model": "dh-avatar",
  "avatar": "9f1c…",
  "audio_url": "https://example.com/voice.mp3",
  "duration": 32
}
```

### 方式 2:用文字 + 音色驱动(一步到位,不用先合成音频)

```json
{
  "model": "dh-avatar",
  "avatar": "9f1c…",
  "voice": "<音色 id>",
  "text": "大家好,今天给大家介绍……",
  "duration": 30
}
```

`voice` 可以是:

- `POST /v1/audio/voices` 克隆出来的音色 **id**(你自己的克隆音色),或
- `GET /v1/audio/voices` 返回的 `presets` 里的平台预设音色 id。

> **`duration` 是必填的**,单位秒。它是我们预留费用的依据 —— 填驱动音频的真实时长,或按文案估算(中文口播约 `字数 ÷ 3.3` 秒)。任务结束后**按上游返回的实际成片秒数结算**,多预留的部分会自动退回;预留额同时是本次出片的费用上限。

提交与轮询用通用视频端点:

```bash
curl https://qianyi.dflop.top/v1/videos/generations \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"dh-avatar","avatar":"9f1c…","audio_url":"https://example.com/voice.mp3","duration":32}'
# → {"id":"…","status":"queued","model":"dh-avatar","created_at":1753…}

curl https://qianyi.dflop.top/v1/videos/generations/<id> \
  -H "Authorization: Bearer $GPUSHARE_API_KEY"
# → {"id":"…","status":"succeeded","video_url":"https://…","expires_at":…}
```

---

## 三、对口型(`dh-lipsync` / `-pro` / `-max`)

给一段**现成的人物视频**换一条音轨,让口型对上。三个档位画质递增、价格递增。

```json
{
  "model": "dh-lipsync-pro",
  "source_video_url": "https://example.com/source.mp4",
  "audio_url": "https://example.com/new-voice.mp3",
  "duration": 45
}
```

成片长度跟随**驱动音频**。源视频和音频都必须是公网可访问的直链。

---

## 四、动作迁移(`dh-motion`)

把一段**动作源视频**里的动作,迁移到 1–7 张人物图上。

```json
{
  "model": "dh-motion",
  "source_video_url": "https://example.com/dance.mp4",
  "face_count": 2,
  "resolution": "standard",
  "content": [
    { "type": "image_url", "image_url": { "url": "https://example.com/person1.jpg" } },
    { "type": "image_url", "image_url": { "url": "https://example.com/person2.jpg" } }
  ],
  "duration": 20
}
```

| 字段 | 说明 |
|---|---|
| `source_video_url` | 动作源视频(公网直链) |
| `content[]` | 1–7 张人物图 |
| `face_count` | 画面里的人数,1–7,应与人物图数量一致 |
| `resolution` | `fast` / `standard`(默认) / `max` —— **档位决定单价**,见下方计价表 |
| `duration` | 必填,按动作源视频时长填 |

成片长度跟随**动作源视频**。

---

## 五、网感剪辑(`clip-compose`)

把一段**有清晰口播**的视频,自动包装成带字幕特效、关键词强调、标题、名片条、模板风格、背景音乐和画中画素材的成片。流程是四步:**挑模板 → 解析字幕 → 提交合成 → 轮询取片**。

- 这把 Key 的模型白名单必须放行 `clip-compose`(模板、分类、字幕解析三个辅助端点也按它判断),否则返回 403 `model_not_allowed`。
- 源视频 **≤ 5 分钟**,必须有清晰人声;公网可访问的 http(s) 直链(本平台不提供上传端点)。
- 成片通常 **20–60 秒**出来。

### 第 1 步:挑模板

```bash
# 模板分类(6 个:高级感 / 热门 / 简约 / 综艺感 / 本地引流 / 其他)
curl https://qianyi.dflop.top/v1/videos/clip-templates/categories \
  -H "Authorization: Bearer $GPUSHARE_API_KEY"
# → {"list":[{"cate_id":"67d402f96574a9003050ea3a","cate_name":"高级感","sort":1}, …]}

# 模板列表(带 cate_id 只看这一类;不带 = 全部模板)
curl "https://qianyi.dflop.top/v1/videos/clip-templates?cate_id=67d402f96574a9003050ea3a" \
  -H "Authorization: Bearer $GPUSHARE_API_KEY"
# → {"list":[{"style_id":"…","name":"…","cover_url":"https://…","demo_url":"https://…","cate_name":"","scene":""}, …],
#    "sid":"","api_version":"old"}
```

模板列表**不分页**:一次返回该分类(或全部)的模板,`sid` 恒为空字符串。`demo_url` 是模板的示例片。挑中的模板把它的 `style_id` 填进合成请求的 `video_style_id`。两个端点都免费。

> 字幕特效、关键词强调、标题、名片条**都由模板渲染**:合成时不套模板,成片里不会出现这些,只会叠上画中画素材。请始终带上 `video_style_id`。只接受本端点列出的模板,其它来源的 `style_id` 会被拒绝(400「这套模板已经下架了」)。

### 第 2 步:解析字幕

```bash
curl https://qianyi.dflop.top/v1/videos/clip-subtitles \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video_url":"https://example.com/talk.mp4"}'
```

**同步**返回,通常 5–10 秒;最长等 240 秒,仍未完成则返回 **504** `upstream_timeout`。响应:

```json
{
  "model": "clip-subtitle",
  "asr_id": "asr_…",
  "api_version": "old",
  "segments": [
    { "showRange": [0, 1750], "content": "很多人做事总纠结" },
    { "showRange": [1750, 2850], "content": "完美才开始" }
  ],
  "sentences": [
    { "showRange": [0, 1750], "content": "很多人做事总纠结" },
    { "showRange": [1750, 2850], "content": "完美才开始" }
  ]
}
```

| 字段 | 说明 |
|---|---|
| `asr_id` | 这次识别的编号 —— **合成时必填** |
| `segments` | **按句**的识别结果:每项一句,`showRange` 是 `[开始毫秒, 结束毫秒]`,不带标点 |
| `sentences` | 与 `segments` 相同(保留这个字段是为了兼容) |

视频里没有识别到人声会返回 400。

### 第 3 步:提交合成

```bash
curl https://qianyi.dflop.top/v1/videos/generations \
  -H "Authorization: Bearer $GPUSHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "clip-compose",
    "video_url": "https://example.com/talk.mp4",
    "asr_id": "<第 2 步返回的 asr_id>",
    "video_style_id": "<第 1 步挑的 style_id>",
    "title": "三分钟看懂复利",
    "enable_title_effect": true,
    "enable_caption_effect": true,
    "enable_keyword_effect": true,
    "name_card": { "name": "张老师", "description": "理财规划师" }
  }'
# → {"id":"…","status":"queued","model":"clip-compose","created_at":1790…}
```

| 字段 | 必填 | 说明 |
|---|---|---|
| `model` | 是 | 固定 `clip-compose` |
| `video_url` | 是 | 源视频直链,与第 2 步解析字幕的是**同一条** |
| `asr_id` | 是 | 第 2 步返回的 `asr_id` |
| `enable_title_effect` | 否 | 是否加标题特效,默认 `false` |
| `enable_caption_effect` | 否 | 是否加字幕特效,默认 `true` |
| `enable_keyword_effect` | 否 | 是否给关键词加强调特效,默认 `true` |
| `title` | 否 | 标题文案,最多 30 字(超出截断) |
| `video_style_id` | 否 | 模板的 `style_id`(第 1 步)。**强烈建议必传**:不套模板时成片没有字幕、标题和名片条 |
| `music_url` | 否 | 背景音乐直链(http(s)) |
| `name_card` | 否 | 名片条 `{"name": "…", "description": "…"}`,`name` 最多 20 字、`description` 最多 40 字 |
| `sentences` | 否 | **改过字幕才传**,规则见下;不传 = 直接用第 2 步的原始识别结果 |
| `pip_config` | 否 | 画中画素材,最多 20 个:`[{"media_url": "https://…", "begin_time": 3000, "end_time": 6000}]`,时间单位**毫秒**,`end_time` > `begin_time` |

#### `sentences`:只能逐句改字

只有当你让用户改了字幕文字时才需要传 `sentences`。规则是**逐句改字**:

```json
"sentences": [
  { "showRange": [0, 1750], "content": "好多人做事总纠结" },
  { "showRange": [1750, 2850], "content": "完美,才开始" }
]
```

- 以第 2 步的 `segments` 为底稿,**句数必须一样、顺序一样**,每句只改 `content`。可以改长改短、加标点。
- **不能拆分、合并或删除句子**:句数对不上会返回 400,并告诉你应该是几句。(上游对句数不同的字幕不会报错,而是悄悄丢掉你的全部改动,或者把成片结尾截掉;平台在提交前就把这种请求挡下来,不会扣费。)
- 每句 `content` 不能为空。
- 时间轴以第 2 步的识别结果为准,你传的 `showRange` 会被忽略。
- 没改字幕就**整个省略** `sentences`,平台会直接使用原始识别结果。
- `asr_id` 必须是第 2 步刚返回的那个;太早以前识别的结果如果已经失效,会返回 400「字幕识别结果已经过期」,重新做一次第 2 步即可。

### 第 4 步:轮询取片

与其它视频任务完全一样,用 [`GET /v1/videos/generations/{id}`](./media-apis.md#轮询) 轮询,建议 5–10 秒一次:

```bash
curl https://qianyi.dflop.top/v1/videos/generations/<id> \
  -H "Authorization: Bearer $GPUSHARE_API_KEY"
# → {"id":"…","status":"succeeded","video_url":"https://…","expires_at":…}
```

### 网感剪辑计价

| 端点 / Model ID | 价格 | 说明 |
|---|---|---|
| `clip-compose`(合成) | **48 / 次** | 每个成功的合成任务一口价,**与视频长短无关**;失败自动全额退款 |
| `clip-subtitle`(字幕解析) | 按次,**当前 0** | 仅成功时扣费;失败 / 超时不扣 |
| 模板列表 / 分类 | 免费 | |

---

## 计价

按秒计费的 SKU,**结算以上游返回的实际成片秒数为准**,提交时按 `duration` 预留、多退。`clip-compose` 按次一口价,不需要传 `duration`。

| Model ID | 用途 | 价格 |
|---|---|---|
| `dh-avatar-create` | 注册数字人形象 | **220.11 / 次** |
| `dh-avatar` | 数字人出片 | 3.96 / 秒 |
| `dh-lipsync` | 对口型 · 标准 | 4.04 / 秒 |
| `dh-lipsync-pro` | 对口型 · 高清 | 8.09 / 秒 |
| `dh-lipsync-max` | 对口型 · 超清 | 12.13 / 秒 |
| `dh-motion` | 动作迁移 | `fast` 4.04 / `standard` 8.09 / `max` 12.13 每秒 |
| `clip-compose` | 网感剪辑 | **48 / 次**(与成片长短无关) |

配套的语音端点(合成 / 克隆)见 [媒体 API](./media-apis.md#post-v1audiospeech)。

---

## 异步与超时约定

- 形象注册、出片与网感剪辑合成**都是异步任务**(网感剪辑的字幕解析是同步的):提交立即返回,之后轮询状态端点。轮询本身免费。
- 出片任务的 `video_url` 是**限时链接**,响应里的 `expires_at` 是过期时间戳 —— 需要长期保存请及时转存。
- 任务失败(上游报错 / 超时过期)**自动全额退款**,不需要你做任何事。
- 形象记录是退款凭据:`pending` 期间调 `DELETE` 会返回 400,请等它进入终态后再删。

## 常见错误

| 状态码 | `code` | 含义 |
|---|---|---|
| 400 | `invalid_request_error` | `avatar` / `voice` 引用不存在、不属于本账号,或还没 `ready`;缺 `duration`;`name` 超长;`source_url` / `video_url` 不是 http(s);字幕解析没识别到人声;`pip_config` 起止时间不合法 |
| 401 | `authentication_error` | Key 无效或已停用 |
| 402 | `quota_exceeded` | 账户余额不足 |
| 403 | `model_not_allowed` | 这把 Key 的模型白名单里没有该 SKU |
| 404 | `model_not_found` | model id 写错,或该 SKU 尚未开放 |
| 503 | `no_channel_available` | 该 SKU 暂无可用上游,稍后重试 |
| 504 | `upstream_timeout` | 字幕解析 240 秒内未完成(未扣费),可重试或换更短的视频 |

错误体形状与其它端点一致,详见 [错误码](./errors.md)。
