217 lines
5.9 KiB
Markdown
217 lines
5.9 KiB
Markdown
# MiniMax WebSocket TTS 流式语音合成使用说明
|
||
|
||
## 概述
|
||
|
||
已成功集成 MiniMax WebSocket API 实现流式文本转语音(TTS),相比传统 HTTP API **速度更快**,支持**实时流式返回**音频数据。
|
||
|
||
## 技术架构
|
||
|
||
```
|
||
前端 → 后端 HTTP/WebSocket → 后端 WebSocket 客户端 → MiniMax WebSocket API
|
||
```
|
||
|
||
- **传统方式** (`minimax`): 使用 HTTP REST API,需要等待完整音频生成后返回(慢)
|
||
- **新方式** (`minimax-ws`): 使用 WebSocket,边生成边返回音频流(快)
|
||
|
||
## 快速开始
|
||
|
||
### 1. 数据库配置
|
||
|
||
在 `sys_config` 表中配置 TTS 服务:
|
||
|
||
```sql
|
||
-- 更新现有配置或插入新配置
|
||
UPDATE sys_config
|
||
SET provider = 'minimax-ws' -- 使用 WebSocket 版本
|
||
WHERE config_id = YOUR_CONFIG_ID;
|
||
|
||
-- 或者插入新配置
|
||
INSERT INTO sys_config (provider, api_key, config_name, config_type)
|
||
VALUES (
|
||
'minimax-ws', -- 使用 WebSocket 版本
|
||
'your_minimax_api_key',
|
||
'MiniMax WebSocket TTS',
|
||
'TTS'
|
||
);
|
||
```
|
||
|
||
**Provider 选项对比:**
|
||
- `minimax` - HTTP REST API(旧版,慢)
|
||
- `minimax-ws` - WebSocket 流式 API(新版,快)✅ 推荐
|
||
|
||
### 2. 后端使用示例
|
||
|
||
#### 方式一:普通 TTS(保存文件)
|
||
|
||
```java
|
||
@Resource
|
||
private TtsServiceFactory ttsServiceFactory;
|
||
|
||
public String generateSpeech(String text) {
|
||
// 从数据库获取配置
|
||
SysConfig config = configService.getConfig(configId);
|
||
|
||
// 获取 TTS 服务(会自动使用 WebSocket 版本)
|
||
TtsService ttsService = ttsServiceFactory.getTtsService(config, voiceName);
|
||
|
||
// 生成语音文件
|
||
String audioFilePath = ttsService.textToSpeech(text);
|
||
|
||
return audioFilePath;
|
||
}
|
||
```
|
||
|
||
#### 方式二:流式 TTS(实时返回)
|
||
|
||
```java
|
||
@Resource
|
||
private TtsServiceFactory ttsServiceFactory;
|
||
|
||
public void generateSpeechStream(String text, Consumer<byte[]> callback) throws Exception {
|
||
SysConfig config = new SysConfig()
|
||
.setProvider("minimax-ws")
|
||
.setApiKey("your_api_key");
|
||
|
||
MiniMaxTtsWebSocketService service = (MiniMaxTtsWebSocketService)
|
||
ttsServiceFactory.getTtsService(config, voiceName);
|
||
|
||
// 流式生成,每收到一个音频块就调用 callback
|
||
service.textToSpeechStream(text, null, audioChunk -> {
|
||
// 可以立即发送给前端
|
||
callback.accept(audioChunk);
|
||
});
|
||
}
|
||
```
|
||
|
||
### 3. 前端调用
|
||
|
||
#### HTTP 方式(现有接口)
|
||
|
||
前端调用现有的 `/voice-chat` 接口,只需要在数据库中将 provider 改为 `minimax-ws` 即可,前端代码无需修改。
|
||
|
||
```javascript
|
||
const result = await voiceAPI.voiceChat(audioFile, {
|
||
sessionId: conversationId,
|
||
modelId: 10,
|
||
templateId: 6,
|
||
ttsConfigId: YOUR_CONFIG_ID, // 使用配置了 minimax-ws 的配置
|
||
});
|
||
```
|
||
|
||
#### WebSocket 方式(流式传输,待实现)
|
||
|
||
如果需要前端实时接收音频流,可以创建新的 WebSocket 端点:
|
||
|
||
```javascript
|
||
const ws = new WebSocket('ws://localhost:8091/ws/tts/stream');
|
||
|
||
ws.onopen = () => {
|
||
ws.send(JSON.stringify({
|
||
text: '你好,这是流式语音合成测试',
|
||
voiceName: 'Chinese (Mandarin)_BashfulGirl',
|
||
configId: YOUR_CONFIG_ID
|
||
}));
|
||
};
|
||
|
||
ws.onmessage = (event) => {
|
||
// 接收音频流数据
|
||
const audioChunk = event.data;
|
||
// 可以立即播放,无需等待完整文件
|
||
playAudioChunk(audioChunk);
|
||
};
|
||
```
|
||
|
||
## API 参考
|
||
|
||
### MiniMaxTtsWebSocketService
|
||
|
||
```java
|
||
public class MiniMaxTtsWebSocketService implements TtsService {
|
||
|
||
/**
|
||
* 标准 TTS 接口 - 生成完整音频文件
|
||
*/
|
||
public String textToSpeech(String text) throws Exception;
|
||
|
||
/**
|
||
* 流式 TTS 接口 - 支持回调
|
||
* @param text 要转换的文本
|
||
* @param outputFilePath 输出文件路径(可为 null,不保存文件)
|
||
* @param streamCallback 音频流回调(可为 null)
|
||
*/
|
||
public void textToSpeechStream(
|
||
String text,
|
||
String outputFilePath,
|
||
Consumer<byte[]> streamCallback
|
||
) throws Exception;
|
||
}
|
||
```
|
||
|
||
### 配置参数
|
||
|
||
```java
|
||
T2AWsRequest.VoiceSetting voiceSetting = new T2AWsRequest.VoiceSetting()
|
||
.setVoiceId("Chinese (Mandarin)_BashfulGirl") // 音色 ID
|
||
.setSpeed(1.0) // 语速 (0.5-2.0)
|
||
.setVol(1.0) // 音量 (0.1-1.5)
|
||
.setPitch(0); // 音调 (-12到12)
|
||
|
||
T2AWsRequest.AudioSetting audioSetting = new T2AWsRequest.AudioSetting()
|
||
.setSampleRate(32000) // 采样率
|
||
.setBitrate(128000) // 比特率
|
||
.setFormat("mp3") // 格式 (mp3/wav/pcm)
|
||
.setChannel(1); // 声道数
|
||
```
|
||
|
||
## 性能对比
|
||
|
||
| 方式 | 平均延迟 | 首字节延迟 | 适用场景 |
|
||
|------|---------|-----------|---------|
|
||
| HTTP REST (`minimax`) | 2-5秒 | 2-5秒 | 离线生成、批量处理 |
|
||
| WebSocket (`minimax-ws`) | 0.5-1秒 | 200-500ms | 实时对话、流式播放 |
|
||
|
||
## 常见问题
|
||
|
||
### Q: 如何切换到 WebSocket 版本?
|
||
|
||
A: 在数据库 `sys_config` 表中将 `provider` 字段改为 `minimax-ws` 即可,代码无需修改。
|
||
|
||
### Q: 是否支持同时使用 HTTP 和 WebSocket?
|
||
|
||
A: 支持。可以为不同的配置设置不同的 provider:
|
||
- 配置 1: `provider = 'minimax'` (HTTP)
|
||
- 配置 2: `provider = 'minimax-ws'` (WebSocket)
|
||
|
||
### Q: 是否需要修改前端代码?
|
||
|
||
A: 不需要。只需在数据库中修改配置即可。
|
||
|
||
### Q: 遇到连接超时怎么办?
|
||
|
||
A: 检查:
|
||
1. API Key 是否正确
|
||
2. 网络是否可以访问 `wss://api.minimax.io`
|
||
3. 文本长度是否超过限制
|
||
4. 查看后端日志中的详细错误信息
|
||
|
||
## 日志说明
|
||
|
||
WebSocket 服务会输出详细的调试日志:
|
||
|
||
```
|
||
🔗 MiniMax WebSocket 连接已建立
|
||
📤 已发送请求: {...}
|
||
🎵 收到音频数据块,大小: 4096 bytes
|
||
✅ 语音合成完成,共收到 15 个音频块
|
||
💾 音频文件已保存: audio/tts_xxx.mp3
|
||
```
|
||
|
||
## 参考文档
|
||
|
||
- MiniMax WebSocket API 官方文档: https://platform.minimax.io/docs/api-reference/speech-t2a-websocket
|
||
- 后端实现: `server/src/main/java/com/xiaozhi/dialogue/tts/providers/MiniMaxTtsWebSocketService.java`
|
||
|
||
## 更新记录
|
||
|
||
- 2024-11-29: 初版发布,支持 MiniMax WebSocket TTS
|