AI 语音生成
AI 语音生成,基于各平台的语音合成(TTS)模型,把文本合成为音频,可以在线播放、下载。目前接入的是:
- 阿里云:通义千问 Qwen-TTS
- MiniMax:Speech 系列
- 字节跳动:豆包语音
- 百度智能云:短文本语音合成
- 腾讯云:长文本语音合成(异步任务)

整个功能,涉及到 3 个表:
- 【配置】
ai_api_key:API 密钥表 - 【配置】
ai_model:模型表 - 【语音】
ai_speech:语音表
补充说明:
ai_api_key、ai_model 已经在 《功能开启》 讲解,就不重复赘述。
# 1. 前置准备
# 1.1 配置 API 密钥
在 [AI 大模型 -> 控制台 -> API 密钥] 菜单,新增对应平台的密钥:
| 平台 | 所属平台 | 密钥 |
|---|---|---|
| 通义千问 | 阿里巴巴(ALIBABA) | 阿里云百炼的 API Key,可以与通义千问对话共用 |
| MiniMax | MiniMax(MINIMAX) | MiniMax 的 API Key,默认地址为 https://api.minimax.cn |
| 豆包语音 | 字节跳动(BYTEDANCE) | 豆包语音的 API Key,不是火山方舟的 API Key |
| 百度 | 百度(BAIDU) | 百度智能云的 API Key |
| 腾讯云 | 腾讯(TENCENT) | SecretId|SecretKey,与腾讯混元对话的 API Key 不同 |
同一平台的对话、语音使用不同的密钥时,为该平台新建多条密钥,模型配置时选择对应的那一条即可。
# 1.2 配置语音模型
在 [AI 大模型 -> 控制台 -> 模型配置] 菜单,新增语音模型:
- 模型类型:选择「音频」,对应 AiModelTypeEnum 的 VOICE(
type为 3) - 所属平台:阿里巴巴、MiniMax、字节跳动、百度、腾讯,其它平台不支持
- API 秘钥:选择同一平台的密钥。密钥的平台与模型的平台不一致时,生成会报错
- 模型标识:见下表
| 平台 | 模型标识 | 文本上限 | 音频格式 | 语速 |
|---|---|---|---|---|
| 通义千问 | qwen3-tts-flash | 600 个字符 | wav | 仅 1 |
| MiniMax | speech-2.8-hd、speech-2.8-turbo、speech-2.6-hd、speech-2.6-turbo、speech-02-hd、speech-02-turbo、speech-01-hd、speech-01-turbo | 9999 个字符 | mp3、wav、flac | 0.5 ~ 2 |
| 豆包语音 | seed-tts-2.0、seed-tts-1.0、seed-tts-1.0-concurr | 10000 个字符 | mp3、ogg_opus | 0.5 ~ 2 |
| 百度 | 自定义,例如说 baidu-tts | GBK 编码小于 1024 字节 | mp3、wav | 0.5 ~ 2 |
| 腾讯云 | 自定义,例如说 tencent-tts | 100000 个字符(页面限制 10000 个) | mp3、wav | 0.6 ~ 2.5 |

友情提示:
- 豆包语音的模型标识,会作为请求头
X-Api-Resource-Id传递。音色需要与模型的版本匹配,例如说seed-tts-2.0使用 2.0 的音色 - 文本超过上限、音频格式或语速不支持时,提交即报错,不会截断文本,也不会替换成其它值
# 1.3 开启定时任务
腾讯云长文本语音合成是异步任务,需要开启 AiSpeechSyncJob 定时任务,按任务编号查询结果。它同时会把超时的语音更新为已失败。
在 [基础设施 -> 定时任务] 菜单,开启「AI 语音同步 Job」任务,处理器名字为 aiSpeechSyncJob,例如说每 10 秒执行一次(0/10 * * * * ?)。具体怎么配置定时任务,可以参考 《定时任务》 文档。
# 2. 语音生成
前端对应 [AI 大模型 -> AI 语音生成] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/ai/speech/index 目录,提供给普通用户使用。
# 2.1 合成语音
左侧是「语音合成」面板,填写后点击提交:
- 模型:只列出已启用的「音频」模型,且平台为以上五个平台
- 朗读文本:按所选模型展示字数上限,百度按 GBK 字节计数
- 音色:服务商的音色编号。下拉框提供推荐音色,例如说通义千问的
Cherry、MiniMax 的male-qn-qingse、豆包语音的zh_female_vv_uranus_bigtts、腾讯云的101001、百度的5003,也可以直接输入服务商的其它音色 - 音频格式、语速:按所选模型展示可选的格式和语速范围
提交后,后端的处理流程如下:
- 校验模型、密钥、参数,通过后插入一条「生成中」的记录,立即返回编号
- 异步调用服务商一次,拿到完整音频后,转存到文件服务,更新为「已完成」;调用失败时,更新为「已失败」,并记录失败原因
- 腾讯云:提交成功后马上保存任务编号,在 180 秒内等待结果;仍未完成的保持「生成中」,之后由定时任务、或页面查询详情时,按任务编号继续查询,不会重新提交
- 超时:没有任务编号的超过 10 分钟、有任务编号的超过 24 小时,更新为「已失败」
# 2.2 我的语音
右侧是「我的语音」列表,生成中的记录会自动刷新,完成后可以:
- 播放、暂停:在底部播放器中播放
- 下载:下载音频文件
- 详情:查看朗读文本、模型、音色、格式、语速、音频大小、完成时间等
- 再次生成:把这条记录的参数回填到左侧面板
- 删除:只能删除已完成、已失败的记录,音频文件保留

它的后端 HTTP 接口,由 yudao-module-ai 模块的 speech 包的 AiSpeechController 实现:
POST /ai/speech/generate:合成语音GET /ai/speech/my-page、GET /ai/speech/get-my:获得【我的】语音分页、详情DELETE /ai/speech/delete-my:删除【我的】语音
这些接口只操作当前登录用户自己的语音。
# 3. 语音管理
前端对应 [AI 大模型 -> 控制台 -> 语音管理] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/ai/speech/manager 目录,提供给管理员使用,查看所有用户的语音记录:
- 查询:按用户、平台、状态、朗读文本(模糊匹配)、创建时间筛选
- 详情:查看朗读文本、模型、音色、格式、语速、音频大小、失败原因等,已完成的可以播放、下载。管理端只查看,不提供「再次生成」,不会重新调用服务商
- 删除:和【我的】一样,只能删除已完成、已失败的记录,音频文件保留

它的后端 HTTP 接口,同样由 AiSpeechController 实现:
GET /ai/speech/page:获得语音分页,对应权限ai:speech:queryGET /ai/speech/get:获得语音详情,对应权限ai:speech:query;不存在时返回空,也不会同步异步任务的结果DELETE /ai/speech/delete:删除语音,对应权限ai:speech:delete
# 4. 语音表
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `ai_speech` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`user_id` bigint NOT NULL COMMENT '用户编号',
`model_id` bigint NOT NULL COMMENT '模型编号',
`platform` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '平台',
`model` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '模型标识',
`api_key_id` bigint NOT NULL COMMENT 'API 密钥编号:提交时绑定,异步任务按它查询结果',
`input_text` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '朗读文本',
`voice` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '音色',
`format` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '音频格式',
`speed` decimal(4,2) DEFAULT NULL COMMENT '语速倍数,最多两位小数;为空时为 1',
`status` tinyint NOT NULL COMMENT '生成状态:10 生成中,20 已完成,30 已失败',
`task_id` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '服务商的任务编号:仅异步任务(腾讯云)',
`audio_url` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '音频地址:文件服务的原始地址,访问时签名',
`audio_size` int DEFAULT NULL COMMENT '音频大小(字节)',
`error_message` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '失败原因(已脱敏)',
`finish_time` datetime DEFAULT NULL COMMENT '完成时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_user_id` (`user_id`) USING BTREE,
KEY `idx_status_create_time` (`status`,`create_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='AI 语音表';
① user_id 字段:对应 system_users 表的 id 字段,表示哪个用户的语音。
② model_id、platform、model、api_key_id 字段:提交时的模型、平台、模型标识、密钥,之后修改模型配置不影响已提交的语音。异步任务按 api_key_id 对应的密钥查询结果。
③ input_text、voice、format、speed 字段:朗读文本、音色、音频格式、语速。
④ status 字段:生成状态,对应 AiSpeechStatusEnum 枚举:10 生成中 → 20 已完成;失败或超时进入 30 已失败。已完成、已失败为终态,迟到的结果不会覆盖。
⑤ task_id 字段:服务商的任务编号,只有腾讯云的异步任务才有。
⑥ audio_url、audio_size 字段:转存到文件服务后的音频地址、大小。不保存服务商的临时地址;使用私有存储时,访问时再签名。
⑦ error_message 字段:失败原因,不包含密钥等敏感信息。
最最最关键的代码!!!大家可以重点看看!!!
AiSpeechServiceImpl 类:
#generateSpeech(...):校验模型、密钥、参数,插入生成中的记录后,异步执行#executeSpeech(...)#executeSpeech(...):调用服务商一次(不自动重试),转存音频,更新为已完成或已失败#syncSpeech():由 AiSpeechSyncJob 定时调用,查询异步任务的结果,并结束超时的语音
各平台的调用,由 AiModelFactoryImpl 的 #getOrCreateTextToSpeechModel(...) 方法创建:TongYiSpeechModel、MiniMaxSpeechModel、DouBaoSpeechModel、BaiduSpeechModel、TencentSpeechModel。