# OnePesr 语音 API — 给 AI 的接入说明

> 把本文件整段粘贴给 AI（或让 AI 读取本文件），AI 即可直接帮你调用四个核心功能：查询音色、声音克隆、声音设计、创建声音模型。

## 0. 快速决策

| 需求 | 用哪个接口 |
|---|---|
| 先查用户有哪些音色可用 | `GET /api/v1/models`（查询声音模型列表） |
| 用现成/已创建的音色朗读文本 | `POST /api/v1/tts`（声音克隆） |
| 没有音色，用一句描述词生成声音朗读 | `POST /api/v1/dubbing`（声音设计） |
| 上传一段录音，注册成可复用音色 | `POST /api/v1/model/create`（创建声音模型） |

- 返回 JSON，`code=0` 即成功，`data.audio_url` 是可直接下载/播放的完整 URL
- 合成是**同步阻塞**返回，耗时约 5–30 秒，HTTP 超时必须设 ≥ 60 秒

## 1. 基础信息

- **BASE（基础地址）**：`https://tts.yirenbang.cc`
- **鉴权**：每个请求携带 `api_key` 与 `api_secret`（JSON 接口放 body，文件上传接口放 form 字段）
- **统一返回**：`{"code": 0或非0, "msg": "可读信息", "data": {...}}`，**先判 code，code=0 才取 data**

## 2. 凭证

调用前先向用户索取两个值（缺一即停，请用户去「密钥管理」页面创建）：

- `api_key`：形如 `op-` 开头的 35 位字符串
- `api_secret`：50 位十六进制字符串

⚠️ 不要把 secret 打印到公开日志；写入配置文件时用环境变量。

## 3. 功能零：查询可用声音模型（先查再合成）

`GET {BASE}/api/v1/models?api_key=xxx&api_secret=xxx`

**成功响应：**

```json
{
  "code": 0,
  "msg": "ok",
  "data": {
    "system_voices": [
      {"model_code": "sys_f_xiaolin", "name": "晓琳", "category": "女声", "gender": "女", "language": "中文", "description": "温柔知性的年轻女声", "type": "system"}
    ],
    "my_voices": [
      {"model_code": "usr_3_1792007397", "name": "我的声音", "category": "男声", "gender": "未知", "language": "中文", "description": "日常说话", "type": "custom"}
    ],
    "total": 34
  }
}
```

- `system_voices`：系统音色（33 个，AI 音色库，所有用户共享）
- `my_voices`：当前 API 密钥用户自己创建的音色（通过功能三创建）
- `model_code`：音色编码，合成时传入此值。系统音色 `sys_` 开头，用户音色 `usr_` 开头

**AI 使用建议**：合成前先调用此接口获取音色列表，让用户选择或按类别自动推荐（女声/男声/童声/方言），避免用户手动输入编码。

## 4. 功能一：声音克隆（指定音色合成）

`POST {BASE}/api/v1/tts`，Content-Type: application/json

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| api_key | string | 是 | API Key |
| api_secret | string | 是 | API Secret |
| text | string | 是 | 待合成文本，1–5000 字符；**按字符扣费**（1 汉字/字母/标点 = 1 额度） |
| model_code | string | 是 | 音色编码，从功能零获取 |
| speed | number | 否 | 语速 0.5–2.0，默认 1.0 |
| emotion_ext | object | 否 | 语气向量，见第 8 节 |

**成功响应（HTTP 200）：**

```json
{
  "code": 0,
  "msg": "合成成功",
  "data": {
    "task_no": "T20261015103012345",
    "audio_url": "https://tts.yirenbang.cc/api/v1/audio?task_no=T...&api_key=...&api_secret=...",
    "chars_used": 17
  }
}
```

- `audio_url` 已带鉴权参数，直接 GET 即得音频二进制（WAV/MP3，由 Content-Type 区分）
- **音频仅保留 1 天**，拿到后请立即转存
- `chars_used` 即本次扣除的额度；**合成失败会自动全额返还**，无需补偿逻辑

**curl 示例：**

```bash
curl -X POST https://tts.yirenbang.cc/api/v1/tts \
  -H "Content-Type: application/json" \
  -d '{"api_key":"op-xxxx","api_secret":"xxxx","model_code":"sys_f_xiaotian","text":"你好，欢迎使用 OnePesr。","emotion_ext":{"happy":0.8}}'
```

**Python 示例（先查音色再合成）：**

```python
import requests

# 1. 查询可用音色
r = requests.get("https://tts.yirenbang.cc/api/v1/models",
    params={"api_key": "op-xxxx", "api_secret": "xxxx"}, timeout=10).json()
assert r["code"] == 0, r["msg"]
voice = r["data"]["system_voices"][0]["model_code"]  # 取第一个系统音色

# 2. 发起合成
r = requests.post("https://tts.yirenbang.cc/api/v1/tts", json={
    "api_key": "op-xxxx",
    "api_secret": "xxxx",
    "model_code": voice,
    "text": "你好，欢迎使用 OnePesr。",
    "speed": 1.0,
    "emotion_ext": {"happy": 0.8},
}, timeout=90).json()
assert r["code"] == 0, r["msg"]
audio = requests.get(r["data"]["audio_url"], timeout=30).content
open("output.wav", "wb").write(audio)
```

## 5. 功能二：声音设计（描述词生成声音并合成）

`POST {BASE}/api/v1/dubbing`，Content-Type: application/json

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| api_key | string | 是 | API Key |
| api_secret | string | 是 | API Secret |
| text | string | 是 | 朗读文本，按字符扣费；引擎限制 1000 字节（约 330 汉字），超长请先切分 |
| design_prompt | string | 是 | 声音描述词，最长 200 字；可从性别、年龄、音色质感、语速、情绪、场景等维度描述，越具体效果越好 |

响应结构与功能一完全一致（task_no / audio_url / chars_used）。

**curl 示例：**

```bash
curl -X POST https://tts.yirenbang.cc/api/v1/dubbing \
  -H "Content-Type: application/json" \
  -d '{"api_key":"op-xxxx","api_secret":"xxxx","design_prompt":"温柔知性的年轻女声，语速平缓，像深夜电台主播","text":"夜深了，愿你有个好梦。"}'
```

## 6. 功能三：创建声音模型（上传录音克隆音色）

`POST {BASE}/api/v1/model/create`，**multipart/form-data**

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| api_key | string | 是 | API Key（form 字段） |
| api_secret | string | 是 | API Secret（form 字段） |
| name | string | 是 | 音色名称，≤32 字 |
| category | string | 是 | 男声 / 女声 / 童声 / 其他 |
| language | string | 否 | 语言，默认「中文」 |
| description | string | 否 | 音色描述，≤100 字 |
| sample | file | 是 | 录音文件，MP3/WAV/M4A，3–60 秒清晰人声（推荐 3–10 秒干声），≤20MB；须为本人或已获授权的声音 |

**成功响应：**

```json
{
  "code": 0,
  "msg": "音色创建成功，已可立即用于合成",
  "data": { "model_code": "usr_3_1792007397", "name": "我的声音", "id": 35 }
}
```

- 返回的 `model_code`（usr_ 开头）**立即可用于功能一**
- 创建模型**不扣费**

**curl 示例：**

```bash
curl -X POST https://tts.yirenbang.cc/api/v1/model/create \
  -F "api_key=op-xxxx" -F "api_secret=xxxx" \
  -F "name=我的声音" -F "category=女声" \
  -F "description=日常说话的声音" \
  -F "sample=@/path/to/recording.wav"
```

## 7. 音色编码（model_code）

- **系统音色**：`sys_` 开头，共 33 个：女声 `sys_f_*`（10 个）、男声 `sys_m_*`（10 个）、童声 `sys_c_*`（5 个）、方言 `sys_d_*`（8 个）。用户可在「AI音色库」页面查看编码与试听。常用示例：`sys_f_xiaotian`（女声·小甜）、`sys_m_haoran`（男声·浩然）、`sys_c_douding`（童声·小豆丁）、`sys_d_yueyu`（粤语·阿强）。
- **用户自建音色**：`usr_` 开头，由功能三创建获得；只能用创建者自己账号的密钥调用（跨用户返回「无权使用该音色」）。
- **建议**：合成前先调用 `GET /api/v1/models` 获取完整列表，避免硬编码编码。

## 8. 语气控制（emotion_ext，仅功能一可选）

8 维情绪向量，每维取值 0–1（步进 0.1 已够），**最多同时给 3 项非 0**（超出服务端自动保留数值最高的 3 项）。不传或全 0 = 跟随参考音频语气。

| 维度 | 含义 | 维度 | 含义 |
|---|---|---|---|
| happy | 开心 | calm | 平静 |
| sad | 悲伤 | melancholic | 忧郁 |
| angry | 愤怒 | afraid | 恐惧 |
| surprised | 惊讶 | disgusted | 厌恶 |

示例：`"emotion_ext": {"happy": 0.7, "surprised": 0.5}`

⚠️ 仅对普通话/多语言音色生效；方言音色传了不报错但也不生效。

## 9. 错误码与处理

| HTTP | code | 含义 | AI 处理方式 |
|---|---|---|---|
| 200 | 0 | 成功 | 取 data |
| 400 | 1 | 参数错误/音色不可用 | 按 msg 修正参数后重试 |
| 401 | 1 | 密钥无效/已停用/账号不可用 | 停止调用，请用户检查密钥 |
| 402 | 1 | 额度不足 | 停止调用，提示用户充值或兑换 CDKEY |
| 500 | 1 | 合成失败（已返还额度） | 可原样重试一次，仍失败则告知用户 |

## 10. 注意事项

1. 合成为同步接口，**timeout 设 60–120 秒**，不要用默认 5 秒。
2. 功能一文本超过 5000 字符、功能二超过 1000 字节，请先自行切分逐段调用后拼接。
3. 每次调用都会计入用户「密钥管理 - 消耗记录」。
4. 批量合成请串行或低并发调用，避免触发服务端风控。
