- 新增 API.md 完整接口文档 - 智能文本分段:长文本按段落/句子/标点边界自动切分(≤2000字/段),逐段TTS后ffmpeg拼接 - /api/tts 支持 voice 参数指定音色 - httpTts JSON 配置增加 style 和 voice 字段 - 批量生成改用并发(Semaphore 3路) - 新增 /health 健康检查端点 - TTS 试听前端增加音色输入 - 清理 import,修复端口不一致
450 lines
9.4 KiB
Markdown
450 lines
9.4 KiB
Markdown
# TTS Book Service API 文档
|
||
|
||
> 基于小米 MiMo TTS 的听书音频转换服务 API 参考
|
||
|
||
## 概览
|
||
|
||
| 分类 | 前缀 | 说明 |
|
||
|------|------|------|
|
||
| 听书 App 接口 | `/api/` | 供听书 App 调用的音频接入接口 |
|
||
| 实时 TTS | `/api/tts` | 实时生成并返回音频流 |
|
||
| 管理接口 | `/admin/api/` | Web 管理界面使用的 CRUD 接口 |
|
||
| 配置文件 | `/httpTts.json` | 听书 App 导入用配置 |
|
||
|
||
**Base URL**: `http://<your-server>:3333`
|
||
|
||
---
|
||
|
||
## 一、实时 TTS 接口
|
||
|
||
### POST `/api/tts`
|
||
|
||
实时调用 MiMo TTS 生成音频,直接返回 MP3 二进制流。
|
||
|
||
> 长文本会自动分段生成并拼接(每段 ≤ 2000 字符,在句末/段落边界智能切分)。
|
||
|
||
#### 请求格式
|
||
|
||
支持两种格式:
|
||
|
||
**1. JSON 格式**(推荐)
|
||
|
||
```http
|
||
POST /api/tts
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"text": "要合成的文本内容",
|
||
"style": "开心",
|
||
"voice": ""
|
||
}
|
||
```
|
||
|
||
**2. Form-urlencoded 格式**(兼容百度风格)
|
||
|
||
```http
|
||
POST /api/tts
|
||
Content-Type: application/x-www-form-urlencoded
|
||
|
||
tex=%E8%A6%81%E5%90%88%E6%88%90%E7%9A%84%E6%96%87%E6%9C%AC
|
||
```
|
||
|
||
#### 参数说明
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| `text` / `tex` | string | ✅ | 要合成的文本(JSON 用 `text`,Form 用 `tex`) |
|
||
| `style` | string | ❌ | 说话风格,如 `开心`、`语速慢`、`东北话`、`像个大将军` 等(见风格参考) |
|
||
| `voice` | string | ❌ | 音色名称,留空使用默认音色(`mimo_default`) |
|
||
|
||
#### 响应
|
||
|
||
- **成功**: `200 OK`,`Content-Type: audio/mpeg`,响应体为 MP3 二进制数据
|
||
- **失败**: `400` / `500`,`Content-Type: application/json`
|
||
|
||
```json
|
||
{
|
||
"status": 40000001,
|
||
"message": "text/tex 不能为空"
|
||
}
|
||
```
|
||
|
||
#### 示例
|
||
|
||
```bash
|
||
# cURL - JSON 格式
|
||
curl -X POST http://localhost:3333/api/tts \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"text": "你好,今天天气真好!", "style": "开心"}' \
|
||
-o output.mp3
|
||
|
||
# cURL - 带音色指定
|
||
curl -X POST http://localhost:3333/api/tts \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"text": "从前有座山,山里有座庙。", "voice": "mimo_male_01"}' \
|
||
-o output.mp3
|
||
```
|
||
|
||
---
|
||
|
||
## 二、听书 App 音频接入接口
|
||
|
||
### GET `/api/book/{book_id}`
|
||
|
||
获取书籍信息及章节列表,供听书 App 调用。
|
||
|
||
#### 路径参数
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `book_id` | string | 书籍唯一标识 |
|
||
|
||
#### 响应
|
||
|
||
```json
|
||
{
|
||
"book_id": "book_9",
|
||
"title": "三体",
|
||
"author": "刘慈欣",
|
||
"chapters": [
|
||
{
|
||
"chapter_id": "chapter_1",
|
||
"app_chapter_id": "chapter1",
|
||
"title": "第一章 疯狂年代",
|
||
"status": "ready",
|
||
"audio_url": "/api/book/book_9/chapter/chapter_1/audio"
|
||
},
|
||
{
|
||
"chapter_id": "chapter_2",
|
||
"app_chapter_id": "chapter2",
|
||
"title": "第二章 寂静的春天",
|
||
"status": "pending",
|
||
"audio_url": null
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
| 字段 | 说明 |
|
||
|------|------|
|
||
| `status` | 章节音频状态:`pending`(待生成) / `generating`(生成中) / `ready`(就绪) / `error`(失败) |
|
||
| `audio_url` | 音频下载地址,仅 `status=ready` 时有值 |
|
||
|
||
#### 错误响应
|
||
|
||
```json
|
||
{"detail": "书籍 book_9 不存在"}
|
||
```
|
||
`404 Not Found`
|
||
|
||
---
|
||
|
||
### GET `/api/book/{book_id}/chapter/{chapter_id}/audio`
|
||
|
||
下载章节 MP3 音频文件。
|
||
|
||
#### 路径参数
|
||
|
||
| 参数 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `book_id` | string | 书籍 ID |
|
||
| `chapter_id` | string | 章节 ID |
|
||
|
||
#### 响应
|
||
|
||
- **成功**: `200 OK`,`Content-Type: audio/mpeg`,MP3 文件流
|
||
- **未生成**: `404`,`{"detail": "音频尚未生成,当前状态: pending"}`
|
||
- **不存在**: `404`,`{"detail": "章节不存在"}`
|
||
|
||
---
|
||
|
||
## 三、管理接口
|
||
|
||
### 书籍管理
|
||
|
||
#### GET `/admin/api/books`
|
||
|
||
获取所有书籍列表。
|
||
|
||
```json
|
||
[
|
||
{"book_id": "book_9", "title": "三体", "author": "刘慈欣"},
|
||
{"book_id": "book_12", "title": "活着", "author": "余华"}
|
||
]
|
||
```
|
||
|
||
#### POST `/admin/api/books`
|
||
|
||
创建新书籍。
|
||
|
||
```http
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"book_id": "book_9",
|
||
"title": "三体",
|
||
"author": "刘慈欣"
|
||
}
|
||
```
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `book_id` | ✅ | 唯一标识 |
|
||
| `title` | ✅ | 书名 |
|
||
| `author` | ❌ | 作者 |
|
||
|
||
**响应**: `{"ok": true, "book_id": "book_9"}`
|
||
|
||
**错误**: `409 Conflict`(book_id 已存在)、`400`(缺少必填字段)
|
||
|
||
#### DELETE `/admin/api/books/{book_id}`
|
||
|
||
删除书籍及其所有章节。
|
||
|
||
**响应**: `{"ok": true}`
|
||
|
||
---
|
||
|
||
### 章节管理
|
||
|
||
#### GET `/admin/api/books/{book_id}/chapters`
|
||
|
||
获取书籍下的章节列表。
|
||
|
||
```json
|
||
[
|
||
{
|
||
"chapter_id": "chapter_1",
|
||
"app_chapter_id": "chapter1",
|
||
"title": "第一章 疯狂年代",
|
||
"text_content": "这是章节文本的前200个字符...",
|
||
"text_length": 15000,
|
||
"status": "ready",
|
||
"error_msg": "",
|
||
"has_audio": true
|
||
}
|
||
]
|
||
```
|
||
|
||
> 注意: `text_content` 只返回前 200 个字符用于预览。完整文本需通过 PUT 接口编辑时获取。
|
||
|
||
#### POST `/admin/api/books/{book_id}/chapters`
|
||
|
||
创建新章节。
|
||
|
||
```json
|
||
{
|
||
"chapter_id": "chapter_1",
|
||
"app_chapter_id": "chapter1",
|
||
"title": "第一章",
|
||
"text_content": "章节正文内容..."
|
||
}
|
||
```
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `chapter_id` | ✅ | 章节唯一标识 |
|
||
| `app_chapter_id` | ❌ | 听书 App 中的章节 ID,默认同 chapter_id |
|
||
| `title` | ❌ | 章节标题 |
|
||
| `text_content` | ❌ | TTS 文本内容 |
|
||
|
||
#### PUT `/admin/api/books/{book_id}/chapters/{chapter_id}`
|
||
|
||
更新章节信息(部分更新)。
|
||
|
||
```json
|
||
{
|
||
"text_content": "更新后的文本内容...",
|
||
"title": "新标题"
|
||
}
|
||
```
|
||
|
||
所有字段均为可选,只更新传入的字段。
|
||
|
||
#### DELETE `/admin/api/books/{book_id}/chapters/{chapter_id}`
|
||
|
||
删除单个章节。
|
||
|
||
---
|
||
|
||
### 音频生成
|
||
|
||
#### POST `/admin/api/books/{book_id}/chapters/{chapter_id}/generate`
|
||
|
||
为单个章节生成音频。
|
||
|
||
> 长文本自动分段生成并拼接(每段 ≤ 2000 字符)。
|
||
|
||
**响应**:
|
||
|
||
```json
|
||
{"ok": true, "status": "ready", "error_msg": ""}
|
||
```
|
||
|
||
或生成失败时:
|
||
|
||
```json
|
||
{"ok": true, "status": "error", "error_msg": "MiMo TTS API 错误: HTTP 502"}
|
||
```
|
||
|
||
#### POST `/admin/api/books/{book_id}/generate-all`
|
||
|
||
批量生成书籍下所有**未就绪**章节的音频。
|
||
|
||
> 按顺序逐章生成,可能需要较长时间。
|
||
|
||
**响应**:
|
||
|
||
```json
|
||
{"ok": true, "total": 5, "chapter_ids": ["ch_1", "ch_2", "ch_3", "ch_4", "ch_5"]}
|
||
```
|
||
|
||
---
|
||
|
||
### TTS 试听
|
||
|
||
#### POST `/admin/api/tts/preview`
|
||
|
||
试听 TTS 效果,返回生成的音频 URL。
|
||
|
||
```json
|
||
{
|
||
"text": "你好,世界!",
|
||
"style": "开心",
|
||
"voice": ""
|
||
}
|
||
```
|
||
|
||
| 字段 | 必填 | 说明 |
|
||
|------|------|------|
|
||
| `text` | ✅ | 试听文本 |
|
||
| `style` | ❌ | 说话风格 |
|
||
| `voice` | ❌ | 音色名称 |
|
||
|
||
**响应**:
|
||
|
||
```json
|
||
{"ok": true, "url": "/audio/_preview/a1b2c3d4.mp3"}
|
||
```
|
||
|
||
---
|
||
|
||
### 配置查看
|
||
|
||
#### GET `/admin/api/config`
|
||
|
||
查看当前服务配置。
|
||
|
||
```json
|
||
{
|
||
"endpoint": "https://api.xiaomimimo.com/v1/chat/completions",
|
||
"model": "mimo-v2-audio-tts",
|
||
"voice": "mimo_default",
|
||
"api_key_masked": "sk-mi****",
|
||
"max_chunk_chars": 2000
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、配置文件
|
||
|
||
### GET `/httpTts.json`
|
||
|
||
提供听书 App 导入用的音频源配置文件(MiMo TTS 单条目)。
|
||
|
||
用户可直接在听书 App 中通过 URL 导入此配置。
|
||
|
||
---
|
||
|
||
## 五、MiMo TTS 风格参考
|
||
|
||
在 `style` 参数中填写风格关键词,MiMo TTS 支持以下类别:
|
||
|
||
### 情感类
|
||
| 风格 | 示例文本 |
|
||
|------|----------|
|
||
| 开心 | 今天真是太棒了!|
|
||
| 悲伤 | 他默默地离开了... |
|
||
| 生气 | 你怎么能这样做!|
|
||
| 平静 | 让我们慢慢来。|
|
||
| 惊讶 | 什么?这不可能!|
|
||
| 温柔 | 没关系,我在这里。|
|
||
|
||
### 语速类
|
||
| 风格 | 效果 |
|
||
|------|------|
|
||
| 语速慢 | 适合冥想、教学 |
|
||
| 语速快 | 适合新闻、解说 |
|
||
| 悄悄话 | 轻声细语 |
|
||
|
||
### 角色类
|
||
| 风格 | 效果 |
|
||
|------|------|
|
||
| 像个大将军 | 威严有力 |
|
||
| 像个小孩 | 稚嫩可爱 |
|
||
| 孙悟空 | 经典猴王 |
|
||
| 像个诗人 | 文艺优雅 |
|
||
| 像个老人 | 沧桑稳重 |
|
||
|
||
### 方言类
|
||
| 风格 | 说明 |
|
||
|------|------|
|
||
| 东北话 | 东北方言 |
|
||
| 四川话 | 四川方言 |
|
||
| 台湾腔 | 台湾口音 |
|
||
| 粤语 | 广东话 |
|
||
| 河南话 | 河南方言 |
|
||
|
||
### 组合使用
|
||
|
||
风格可以组合,例如:
|
||
|
||
```json
|
||
{
|
||
"text": "今天天气真好",
|
||
"style": "开心 语速快"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 六、错误码参考
|
||
|
||
| HTTP 状态码 | status 字段 | 含义 |
|
||
|-------------|-------------|------|
|
||
| 400 | 40000001 | 请求参数缺失或无效 |
|
||
| 404 | - | 资源不存在(书籍/章节/音频文件) |
|
||
| 409 | - | 资源冲突(ID 已存在) |
|
||
| 500 | 50000002 | 服务端错误(未配置 API Key 等) |
|
||
| 502 | - | MiMo TTS API 调用失败 |
|
||
|
||
---
|
||
|
||
## 七、文本自动分段机制
|
||
|
||
当文本超过 **2000 字符**时,服务自动进行智能分段:
|
||
|
||
### 分段策略
|
||
|
||
按优先级尝试在以下位置切分:
|
||
|
||
1. **段落边界** — `\n\n`
|
||
2. **换行符** — `\n`
|
||
3. **中文句末标点** — `。!?…`
|
||
4. **英文句末标点** — `.!?`
|
||
5. **分号** — `;;`
|
||
6. **逗号** — `,,`
|
||
7. **硬切** — 以上都不匹配时按长度截断
|
||
|
||
### 处理流程
|
||
|
||
```
|
||
原始文本 (10000字)
|
||
→ 智能分段 → [段1(1800字), 段2(1950字), 段3(2000字), 段4(1900字), 段5(2350字)]
|
||
→ 逐段调用 MiMo TTS → [wav1, wav2, wav3, wav4, wav5]
|
||
→ ffmpeg 拼接 → 最终 MP3
|
||
```
|
||
|
||
此过程对用户完全透明,`/api/tts` 和章节音频生成均自动支持。
|