Merge pull request #1518 from shane04111/add_local_tts_change_voice

update: 添加本地tts支援面板的"角色音色"
This commit is contained in:
hrz
2025-06-30 10:48:15 +08:00
committed by GitHub
11 changed files with 87 additions and 19 deletions
@@ -72,6 +72,8 @@ public class ConfigServiceImpl implements ConfigService {
null, null,
null, null,
null, null,
null,
null,
agent.getVadModelId(), agent.getVadModelId(),
agent.getAsrModelId(), agent.getAsrModelId(),
null, null,
@@ -108,9 +110,13 @@ public class ConfigServiceImpl implements ConfigService {
} }
// 获取音色信息 // 获取音色信息
String voice = null; String voice = null;
String referenceAudio = null;
String referenceText = null;
TimbreDetailsVO timbre = timbreService.get(agent.getTtsVoiceId()); TimbreDetailsVO timbre = timbreService.get(agent.getTtsVoiceId());
if (timbre != null) { if (timbre != null) {
voice = timbre.getTtsVoice(); voice = timbre.getTtsVoice();
referenceAudio = timbre.getReferenceAudio();
referenceText = timbre.getReferenceText();
} }
// 构建返回数据 // 构建返回数据
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
@@ -163,6 +169,8 @@ public class ConfigServiceImpl implements ConfigService {
agent.getSystemPrompt(), agent.getSystemPrompt(),
agent.getSummaryMemory(), agent.getSummaryMemory(),
voice, voice,
referenceAudio,
referenceText,
agent.getVadModelId(), agent.getVadModelId(),
agent.getAsrModelId(), agent.getAsrModelId(),
agent.getLlmModelId(), agent.getLlmModelId(),
@@ -179,7 +187,7 @@ public class ConfigServiceImpl implements ConfigService {
/** /**
* 构建配置信息 * 构建配置信息
* *
* @param paramsList 系统参数列表 * @param config 系统参数列表
* @return 配置信息 * @return 配置信息
*/ */
private Object buildConfig(Map<String, Object> config) { private Object buildConfig(Map<String, Object> config) {
@@ -250,21 +258,25 @@ public class ConfigServiceImpl implements ConfigService {
/** /**
* 构建模块配置 * 构建模块配置
* *
* @param prompt 提示词 * @param prompt 提示词
* @param voice 音色 * @param voice 音色
* @param vadModelId VAD模型ID * @param referenceAudio 参考音频路径
* @param asrModelId ASR模型ID * @param referenceText 参考文本
* @param llmModelId LLM模型ID * @param vadModelId VAD模型ID
* @param ttsModelId TTS模型ID * @param asrModelId ASR模型ID
* @param memModelId 记忆模型ID * @param llmModelId LLM模型ID
* @param intentModelId 意图模型ID * @param ttsModelId TTS模型ID
* @param result 结果Map * @param memModelId 记忆模型ID
* @param intentModelId 意图模型ID
* @param result 结果Map
*/ */
private void buildModuleConfig( private void buildModuleConfig(
String assistantName, String assistantName,
String prompt, String prompt,
String summaryMemory, String summaryMemory,
String voice, String voice,
String referenceAudio,
String referenceText,
String vadModelId, String vadModelId,
String asrModelId, String asrModelId,
String llmModelId, String llmModelId,
@@ -290,8 +302,10 @@ public class ConfigServiceImpl implements ConfigService {
if (model.getConfigJson() != null) { if (model.getConfigJson() != null) {
typeConfig.put(model.getId(), model.getConfigJson()); typeConfig.put(model.getId(), model.getConfigJson());
// 如果是TTS类型,添加private_voice属性 // 如果是TTS类型,添加private_voice属性
if ("TTS".equals(modelTypes[i]) && voice != null) { if ("TTS".equals(modelTypes[i])){
((Map<String, Object>) model.getConfigJson()).put("private_voice", voice); if (voice != null) ((Map<String, Object>) model.getConfigJson()).put("private_voice", voice);
if (referenceAudio != null) ((Map<String, Object>) model.getConfigJson()).put("ref_audio", referenceAudio);
if (referenceText != null) ((Map<String, Object>) model.getConfigJson()).put("ref_text", referenceText);
} }
// 如果是Intent类型,且type=intent_llm,则给他添加附加模型 // 如果是Intent类型,且type=intent_llm,则给他添加附加模型
if ("Intent".equals(modelTypes[i])) { if ("Intent".equals(modelTypes[i])) {
@@ -26,6 +26,12 @@ public class TimbreDataDTO {
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;
@Schema(description = "参考音频路径")
private String referenceAudio;
@Schema(description = "參考文本")
private String referenceText;
@Schema(description = "排序") @Schema(description = "排序")
@Min(value = 0, message = "{sort.number}") @Min(value = 0, message = "{sort.number}")
private long sort; private long sort;
@@ -34,6 +34,12 @@ public class TimbreEntity {
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;
@Schema(description = "参考音频路径")
private String referenceAudio;
@Schema(description = "參考文本")
private String referenceText;
@Schema(description = "排序") @Schema(description = "排序")
private long sort; private long sort;
@@ -25,6 +25,12 @@ public class TimbreDetailsVO implements Serializable {
@Schema(description = "备注") @Schema(description = "备注")
private String remark; private String remark;
@Schema(description = "参考音频路径")
private String referenceAudio;
@Schema(description = "參考文本")
private String referenceText;
@Schema(description = "排序") @Schema(description = "排序")
private long sort; private long sort;
@@ -0,0 +1,3 @@
ALTER TABLE `ai_tts_voice`
ADD COLUMN `reference_audio` VARCHAR(500) DEFAULT NULL COMMENT '参考音频路径' AFTER `remark`,
ADD COLUMN `reference_text` VARCHAR(500) DEFAULT NULL COMMENT '参考文本' AFTER `reference_audio`;
@@ -205,6 +205,13 @@ databaseChangeLog:
- sqlFile: - sqlFile:
encoding: utf8 encoding: utf8
path: classpath:db/changelog/202506080955.sql path: classpath:db/changelog/202506080955.sql
- changeSet:
id: 202506091720
author: shane0411
changes:
- sqlFile:
encoding: utf8
path: classpath:db/changelog/202506091720.sql
- changeSet: - changeSet:
id: 202506161101 id: 202506161101
author: hrz author: hrz
@@ -34,6 +34,8 @@ export default {
languages: params.languageType, languages: params.languageType,
name: params.voiceName, name: params.voiceName,
remark: params.remark, remark: params.remark,
referenceAudio: params.referenceAudio,
referenceText: params.referenceText,
sort: params.sort, sort: params.sort,
ttsModelId: params.ttsModelId, ttsModelId: params.ttsModelId,
ttsVoice: params.voiceCode, ttsVoice: params.voiceCode,
@@ -75,6 +77,8 @@ export default {
languages: params.languageType, languages: params.languageType,
name: params.voiceName, name: params.voiceName,
remark: params.remark, remark: params.remark,
referenceAudio: params.referenceAudio,
referenceText: params.referenceText,
ttsModelId: params.ttsModelId, ttsModelId: params.ttsModelId,
ttsVoice: params.voiceCode, ttsVoice: params.voiceCode,
voiceDemo: params.voiceDemo || '' voiceDemo: params.voiceDemo || ''
@@ -74,6 +74,18 @@
<span v-else>{{ scope.row.remark }}</span> <span v-else>{{ scope.row.remark }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="音频路径" align="center">
<template slot-scope="scope">
<el-input v-if="scope.row.editing" v-model="scope.row.referenceAudio" placeholder="这里是参考音频路径 (本地模型用)"></el-input>
<span v-else>{{ scope.row.referenceAudio }}</span>
</template>
</el-table-column>
<el-table-column label="音频文本" align="center">
<template slot-scope="scope">
<el-input v-if="scope.row.editing" v-model="scope.row.referenceText" placeholder="这里是参考音频文本 (本地模型用)"></el-input>
<span v-else>{{ scope.row.referenceText }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150"> <el-table-column label="操作" align="center" width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<template v-if="!scope.row.editing"> <template v-if="!scope.row.editing">
@@ -206,6 +218,8 @@ export default {
voiceName: item.name || '未命名音色', voiceName: item.name || '未命名音色',
languageType: item.languages || '', languageType: item.languages || '',
remark: item.remark || '', remark: item.remark || '',
referenceAudio: item.referenceAudio || '',
referenceText: item.referenceText || '',
voiceDemo: item.voiceDemo || '', voiceDemo: item.voiceDemo || '',
selected: false, selected: false,
editing: false, editing: false,
@@ -351,6 +365,8 @@ export default {
voiceName: row.voiceName, voiceName: row.voiceName,
languageType: row.languageType, languageType: row.languageType,
remark: row.remark, remark: row.remark,
referenceAudio: row.referenceAudio,
referenceText: row.referenceText,
ttsModelId: this.ttsModelId, ttsModelId: this.ttsModelId,
voiceDemo: row.voiceDemo || '', voiceDemo: row.voiceDemo || '',
sort: row.sort sort: row.sort
@@ -432,6 +448,8 @@ export default {
languageType: '中文', languageType: '中文',
voiceDemo: '', voiceDemo: '',
remark: '', remark: '',
referenceAudio: '',
referenceText: '',
selected: false, selected: false,
editing: true, editing: true,
sort: maxSort + 1 sort: maxSort + 1
@@ -85,8 +85,12 @@ class TTSProvider(TTSProviderBase):
self.reference_id = ( self.reference_id = (
None if not config.get("reference_id") else config.get("reference_id") None if not config.get("reference_id") else config.get("reference_id")
) )
self.reference_audio = parse_string_to_list(config.get("reference_audio")) self.reference_audio = parse_string_to_list(
self.reference_text = parse_string_to_list(config.get("reference_text")) config.get('ref_audio')if config.get('ref_audio') else config.get("reference_audio")
)
self.reference_text = parse_string_to_list(
config.get('ref_text')if config.get('ref_text') else config.get("reference_text")
)
self.format = config.get("response_format", "wav") self.format = config.get("response_format", "wav")
self.audio_file_type = config.get("response_format", "wav") self.audio_file_type = config.get("response_format", "wav")
self.api_key = config.get("api_key", "YOUR_API_KEY") self.api_key = config.get("api_key", "YOUR_API_KEY")
@@ -12,8 +12,8 @@ class TTSProvider(TTSProviderBase):
super().__init__(config, delete_audio_file) super().__init__(config, delete_audio_file)
self.url = config.get("url") self.url = config.get("url")
self.text_lang = config.get("text_lang", "zh") self.text_lang = config.get("text_lang", "zh")
self.ref_audio_path = config.get("ref_audio_path") self.ref_audio_path = config.get('ref_audio') if config.get('ref_audio') else config.get("ref_audio_path")
self.prompt_text = config.get("prompt_text") self.prompt_text = config.get('ref_text') if config.get('ref_text') else config.get("prompt_text")
self.prompt_lang = config.get("prompt_lang", "zh") self.prompt_lang = config.get("prompt_lang", "zh")
# 处理空字符串的情况 # 处理空字符串的情况
@@ -11,8 +11,8 @@ class TTSProvider(TTSProviderBase):
def __init__(self, config, delete_audio_file): def __init__(self, config, delete_audio_file):
super().__init__(config, delete_audio_file) super().__init__(config, delete_audio_file)
self.url = config.get("url") self.url = config.get("url")
self.refer_wav_path = config.get("refer_wav_path") self.refer_wav_path = config.get('ref_audio')if config.get('ref_audio') else config.get("refer_wav_path")
self.prompt_text = config.get("prompt_text") self.prompt_text = config.get('ref_text')if config.get('ref_text') else config.get("prompt_text")
self.prompt_language = config.get("prompt_language") self.prompt_language = config.get("prompt_language")
self.text_language = config.get("text_language", "audo") self.text_language = config.get("text_language", "audo")