diff --git a/tts_api_architecture.html b/tts_api_architecture.html deleted file mode 100644 index 76a0607..0000000 --- a/tts_api_architecture.html +++ /dev/null @@ -1,444 +0,0 @@ - - - - - -TTS-API 架构设计 — TTS 版 New-API - - - - -

TTS-API

-

TTS 版 New-API 架构设计 · 多 Provider 统一 TTS 网关 · 2026-05-21

- -

1. 项目定位

- -

参考 new-api 的设计理念,TTS-API 定位为企业级 TTS 统一网关与资产管理平台,核心能力:

- - - - - - - -
能力维度说明
统一接入以 OpenAI /v1/audio/speech 为唯一入口,屏蔽火山引擎、阿里、Azure、讯飞等上游差异
统一音色定义标准音色命名体系,自动映射到各 Provider 的实际音色 ID
统一计费按字符数 / 时长计费,支持配额管理与成本核算
统一治理权限分组、速率限制、渠道故障切换、审计日志、可视化看板
- -

2. 与 new-api 的关键差异

- - - - - - - - - - -
维度new-api(LLM)TTS-API(本项目)
核心接口/v1/chat/completions/v1/audio/speech
协议转换OpenAI ↔ Claude ↔ Gemini 互转只需转到各 Provider 原生格式(单向)
模型映射模型名 → 渠道选择音色映射:标准 voice → 各 Provider 实际音色 ID
(这是最大难点)
输出处理文本 / JSON 流二进制音频流,需处理格式转换(wav/mp3/pcm)
计费单位Token 数字符数 + 音频时长
缓存语义缓存(相同问题命中)音频缓存(相同文本+音色 → 直接返回已合成音频)
流式SSE 文本流音频流式推送(边合成边返回,首字节延迟是关键指标)
- -

3. 整体分层架构

- -
-┌─────────────────────────────────────────────────────────────────┐ -│ 客户端 / 应用层 │ -│ OpenAI SDK │ REST API │ Web 管理后台 │ -└────────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────────▼────────────────────────────────────┐ -│ Gin HTTP Server │ -│ ┌──────────────────────────────────────────────────────────────┐│ -│ │ 路由层 (router/) ││ -│ │ /v1/audio/speech /api/* (管理) /web/* (前端静态) ││ -│ └──────────────────────────────────────────────────────────────┘│ -└────────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────────▼────────────────────────────────────┐ -│ 中间件层 (middleware/) │ -│ 认证(JWT/API Key) │ 限流(IP/用户) │ 日志 │ CORS │ 请求分发 │ -└────────────────────────────┬────────────────────────────────────┘ - │ -┌────────────────────────────▼────────────────────────────────────┐ -│ 控制器层 (controller/) │ -│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ -│ │ 语音合成 │ │ 用户管理 │ │ 渠道管理 │ │ 计费 & 统计 │ │ -│ │ controller│ │controller │ │controller │ │ controller │ │ -│ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │ -└────────────────────────────┬────────────────────────────────────┘ - │ - ┌─────────────────────┼─────────────────────┐ - │ │ │ -┌──────▼──────┐ ┌────────▼────────┐ ┌───────▼──────┐ -│ 服务层 │ │ 适配器层 │ │ 数据层 │ -│ (service/) │ │ (adapter/) │ │ (model/) │ -│ │ │ │ │ │ -│ · 配额管理 │ │ 接口定义 │ │ GORM ORM │ -│ · 音频缓存 │ │ · volcano │ │ │ -│ · 音色映射 │ │ · aliyun │ │ │ -│ · 格式转换 │ │ · azure │ │ │ -│ · 计费服务 │ │ · tencent │ │ │ -│ · 渠道调度 │ │ · xunfei │ │ │ -└──────────────┘ │ · openai │ └───────┬──────┘ - │ · fish_audio │ │ - │ · bert_vits │ ┌───────┼───────┐ - └─────────────────┘ │ │ │ - ┌──────▼──┐ ┌──▼──┐ ┌─▼────┐ - │ SQLite │ │MySQL│ │ PG │ - └─────────┘ └─────┘ └──────┘ -
- -

4. 请求处理全流程

- -
- 客户端发送 OpenAI 格式 TTS 请求 - │ - ▼ - [1] Gin 路由匹配 → /v1/audio/speech - │ - ▼ - [2] 中间件链:认证(API Key) → 用户级限流 → 请求日志 - │ - ▼ - [3] 控制器:解析请求 { model, input, voice, speed, response_format } - │ - ▼ - [4] 音色映射服务:标准 voice 名 → 查找可用渠道 → 映射为渠道实际音色ID - │ 例: "gentle_male" → 火山引擎(zh_male_qingxin) - │ → Azure(zh-CN-YunxiNeural) - │ → 阿里(cosyvoice-v1-longxiaochun) - ▼ - [5] 渠道调度器:按权重+可用性选择最优渠道,失败自动切换 - │ - ▼ - [6] 适配器:将 OpenAI 请求转为 Provider 原生格式,发送请求 - │ - ▼ - [7] 音频处理:接收二进制音频 → 格式转换(如需) → 写入音频缓存 - │ - ▼ - [8] 计费结算:按字符数/时长扣费,记录日志 - │ - ▼ - [9] 返回响应:Content-Type: audio/wav,流式或整段返回 -
- -

5. 核心设计:适配器接口

- -

参考 new-api 的 Adaptor 接口设计,TTS 版适配器接口如下:

- -
-// adapter.go — TTS Provider 统一接口 - -type TTSAdapter interface { - // 初始化:传入渠道配置(API Key / Resource ID / 默认音色等) - Init(info *TTSRelayInfo) error - - // 构建上游请求 URL - BuildRequestURL(info *TTSRelayInfo) (string, error) - - // 设置请求头(鉴权、Content-Type 等) - SetupRequestHeader(c *gin.Context, req *http.Request, info *TTSRelayInfo) error - - // 核心:将 OpenAI 格式请求转为 Provider 原生请求体 - ConvertRequest(info *TTSRelayInfo, req *dto.OpenAITTSRequest) (any, error) - - // 发送请求到上游 - DoRequest(c *gin.Context, info *TTSRelayInfo, body io.Reader) (*http.Response, error) - - // 处理上游响应:提取音频、统计字符数/时长、返回标准结构 - DoResponse(c *gin.Context, resp *http.Response, info *TTSRelayInfo) (*dto.TTSUsage, *dto.TTSError) - - // 返回此渠道支持的音色列表(用于音色映射表构建) - GetVoiceList() []ProviderVoice - - // 渠道标识 - GetChannelName() string - - // 是否支持流式 TTS - SupportStreaming() bool -} - -// ProviderVoice 各 Provider 的音色结构 -type ProviderVoice struct { - ProviderID string // Provider 内部音色 ID,如 "zh_female_qingxin" - Language string // zh-CN / en-US / ja-JP - Gender string // male / female - Style string // 风格标签,如 "news" / "story" / "chat" - Description string // 音色描述 -} -
- -

6. 核心设计:音色映射系统

- -

这是 TTS 网关区别于 LLM 网关的最大难点与核心创新点。LLM 网关只需按模型名路由,但 TTS 需要一套跨 Provider 的音色统一体系。

- -
- 标准音色命名空间 - ┌──────────────────────────────────┐ - │ tts-1-gentle-male │ - │ tts-1-gentle-female │ - │ tts-1-news-male │ - │ tts-1-story-female │ - │ tts-1-casual-male │ - │ ... │ - └──────────┬───────────────────────┘ - │ 音色映射表 (voice_mapping) - │ - ┌───────────────┼───────────────┬───────────────┐ - │ │ │ │ - ▼ ▼ ▼ ▼ -┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ -│ 火山引擎 │ │ Azure │ │ 阿里 │ │ 讯飞 │ -│ │ │ │ │ │ │ │ -│zh_male_ │ │zh-CN- │ │cosyvoice│ │x4_ling │ -│qingxin │ │Yunxi │ │-v1-long │ │xiaoxuan │ -│ │ │Neural │ │xiaochun │ │ │ -└─────────┘ └─────────┘ └─────────┘ └─────────┘ -
- -

6.1 音色映射表结构

- -
-// voice_mapping 表 (数据库) -type VoiceMapping struct { - ID uint - StandardVoice string // "tts-1-gentle-male" - ChannelID uint // 渠道 ID - ProviderVoice string // Provider 原始音色 ID - Priority int // 优先级(同一标准音色多渠道时,优先选谁) - IsDefault bool // 是否为该标准音色的默认渠道 -} - -// 示例数据: -// standard_voice | channel | provider_voice | priority -// tts-1-gentle-male | 火山引擎 | zh_male_qingxin | 1 -// tts-1-gentle-male | Azure | zh-CN-YunxiNeural | 2 -// tts-1-gentle-male | 阿里 | cosyvoice-v1-longxiaochun| 3 -
- -

6.2 音色发现与自动映射建议

- -

每个 Provider 适配器实现 GetVoiceList(),系统启动或渠道更新时自动拉取,通过语言+性别+风格标签与标准命名空间做相似度匹配,自动生成映射建议,管理员在 Web UI 审核确认即可。

- -

7. 渠道调度与故障切换

- -
- 请求 → 查找"tts-1-gentle-male"可用的渠道列表 - │ - ▼ - 按 priority 排序 → 加权随机选择一个渠道 - │ - ▼ - 适配器发送请求 → 成功? - ├── 是 → 返回音频,记录成功 - │ - └── 否 → 标记渠道失败 - │ - ▼ - 自动切换 priority+1 的渠道重试 - │ - ▼ - 所有渠道失败 → 返回 503 + 错误详情 -
- -

8. 项目目录结构

- -
-tts-api/ -├── main.go # 入口:初始化 DB、路由、启动服务 -├── go.mod / go.sum -├── .env.example # 环境变量示例 -├── Dockerfile # 多阶段构建 -├── docker-compose.yml -│ -├── router/ # 路由层 -│ ├── main.go # 路由聚合 -│ ├── api-router.go # /api/* 管理接口 -│ ├── relay-router.go # /v1/audio/speech TTS 代理 -│ └── web-router.go # /web/* 管理后台静态资源 -│ -├── middleware/ # 中间件 -│ ├── auth.go # JWT + API Key 认证 -│ ├── rate-limit.go # 用户/IP 级别限流 -│ ├── cors.go # 跨域 -│ └── logger.go # 请求日志 -│ -├── controller/ # 控制器 -│ ├── tts.go # TTS 合成入口(核心) -│ ├── channel.go # 渠道 CRUD -│ ├── user.go # 用户管理 -│ ├── token.go # API Key 管理 -│ ├── voice.go # 音色映射管理 -│ └── billing.go # 计费统计 -│ -├── service/ # 服务层 -│ ├── voice_mapping/ # 音色映射服务(核心) -│ │ └── matcher.go # 自动匹配 & 建议 -│ ├── channel_scheduler/ # 渠道调度(权重/故障切换) -│ │ └── scheduler.go -│ ├── audio_cache/ # 音频缓存(相同文本+音色命中) -│ │ └── cache.go -│ ├── audio_convert/ # 音频格式转换(ffmpeg 封装) -│ │ └── converter.go -│ ├── billing/ # 计费服务 -│ │ └── billing.go -│ └── quota/ # 配额管理 -│ └── quota.go -│ -├── adapter/ # 适配器层(核心!) -│ ├── adapter.go # TTSAdapter 接口定义 -│ ├── volcano/ # 火山引擎 TTS -│ │ └── volcano.go -│ ├── aliyun/ # 阿里云 CosyVoice / 百炼 -│ │ └── aliyun.go -│ ├── azure/ # 微软 Azure TTS -│ │ └── azure.go -│ ├── tencent/ # 腾讯云 TTS -│ │ └── tencent.go -│ ├── xunfei/ # 讯飞 TTS -│ │ └── xunfei.go -│ ├── openai/ # OpenAI TTS(基准) -│ │ └── openai.go -│ ├── fish_audio/ # Fish Audio(开源) -│ │ └── fish_audio.go -│ └── bert_vits/ # Bert-VITS2(开源自建) -│ └── bert_vits.go -│ -├── model/ # 数据模型 (GORM) -│ ├── user.go -│ ├── channel.go # 渠道(Provider 配置) -│ ├── token.go # API Key / Token -│ ├── voice_mapping.go # 音色映射 -│ ├── usage_record.go # 用量记录 -│ └── audio_cache.go # 音频缓存记录 -│ -├── dto/ # 请求/响应结构体 -│ ├── openai_tts.go # OpenAI TTS 请求/响应格式 -│ ├── relay_info.go # 中继上下文(TTSRelayInfo) -│ └── common.go # 通用响应 -│ -├── setting/ # 配置管理 (Viper) -│ └── setting.go -│ -├── common/ # 通用工具 -│ ├── utils.go -│ └── constants.go -│ -└── web/ # React 管理后台 - ├── src/ - │ ├── pages/ - │ │ ├── Dashboard # 数据看板 - │ │ ├── Channels # 渠道管理 - │ │ ├── VoiceMapping # 音色映射配置 - │ │ ├── Users # 用户管理 - │ │ ├── Tokens # API Key - │ │ ├── Billing # 计费 & 用量 - │ │ └── Logs # 调用日志 - │ └── ... - └── package.json -
- -

9. 管理后台页面规划

- - - - - - - - - - -
页面功能
Dashboard今日合成次数、字符数、时长、费用、渠道健康状态、QPS 曲线
渠道管理添加/编辑 Provider(API Key、Resource ID、权重、并发上限)
音色映射核心页面:标准音色 ↔ 各渠道音色 ID 的映射表,支持自动匹配建议与手动调整
API Key生成/管理用户 API Key,绑定分组与配额
用户管理用户 CRUD、分组、角色(Admin / User)
计费统计按用户/渠道/日期维度的用量与费用报表
调用日志每次 TTS 请求的详细日志(文本、音色、渠道、耗时、费用)
- -

10. 一期 vs 二期路线图

- -

一期(MVP,你现有的 Volcano-Engine-TTS-UI 升级版)

- - - - - - - - -
模块内容
适配器火山引擎 + Azure + 阿里云,3 个 Provider
接口/v1/audio/speech,OpenAI 兼容
音色映射硬编码映射表(配置文件),先跑通再抽象
计费简单字符数计数 + 日志
管理后台极简版:渠道配置页面 + 用量看板
数据库SQLite,单文件部署
- -

二期(完整版)

- - - - - - - - - - -
模块内容
适配器扩到 8+ Provider(讯飞、腾讯、Fish Audio、Bert-VITS2、OpenAI)
音色映射数据库驱动 + Web UI 可视化管理 + 自动匹配建议
计费字符数/时长双维度计费,用户配额,欠费阻断
缓存Redis 音频缓存,相同文本+音色直接命中
流式支持流式 TTS(SSE 推送音频 chunk),降低首字节延迟
管理后台完整 React 后台(参考 new-api 的 Semi Design UI)
数据库MySQL / PostgreSQL 支持
部署Docker Compose 一键部署
- -

11. 关键工程建议

- -
    -
  1. 从你现有的火山引擎适配器起步,先抽象出 TTSAdapter 接口,接入 2~3 个 Provider 验证接口设计是否合理,不要一上来就搞 8 个适配器。
  2. -
  3. 音色映射先硬编码,跑通流程后再做成数据库驱动的 Web UI。映射表是长期维护工作,需要社区共建。
  4. -
  5. 音频格式转换用 ffmpeg,Go 侧通过 exec.Command 调用或使用 go-ffmpeg 绑定。各 Provider 输出格式不同(wav / mp3 / pcm),统一转码是刚需。
  6. -
  7. 渠道调度直接复用 new-api 的加权随机 + 故障重试思路,这是成熟的模式,不需要重新发明。
  8. -
  9. 管理后台前期可以不写,SQLite + 配置文件就能用;等 Provider 多了再补 React 前端。
  10. -
  11. 考虑直接 fork new-api 改造:new-api 的渠道管理、用户系统、计费框架、中间件、部署方案都是现成的,你只需要把 relay 层的 LLM 适配器替换成 TTS 适配器,再加音色映射模块。这比从零搭建快得多。
  12. -
- - - - - \ No newline at end of file