update: 增加TTS音色语种选择

This commit is contained in:
Sakura-RanChen
2026-02-09 15:28:31 +08:00
parent 520e24a54e
commit 4ea3bea85c
21 changed files with 220 additions and 61 deletions
@@ -41,6 +41,9 @@ public class AgentUpdateDTO implements Serializable {
@Schema(description = "音色标识", example = "voice_02", nullable = true)
private String ttsVoiceId;
@Schema(description = "音色语言", example = "普通话", nullable = true)
private String ttsLanguage;
@Schema(description = "记忆模型标识", example = "mem_model_02", nullable = true)
private String memModelId;
@@ -45,6 +45,9 @@ public class AgentEntity {
@Schema(description = "音色标识")
private String ttsVoiceId;
@Schema(description = "音色语言")
private String ttsLanguage;
@Schema(description = "记忆模型标识")
private String memModelId;
@@ -64,6 +64,11 @@ public class AgentTemplateEntity implements Serializable {
*/
private String ttsVoiceId;
/**
* 音色语言
*/
private String ttsLanguage;
/**
* 记忆模型标识
*/
@@ -282,6 +282,9 @@ public class AgentServiceImpl extends BaseServiceImpl<AgentDao, AgentEntity> imp
if (dto.getTtsVoiceId() != null) {
existingEntity.setTtsVoiceId(dto.getTtsVoiceId());
}
if (dto.getTtsLanguage() != null) {
existingEntity.setTtsLanguage(dto.getTtsLanguage());
}
if (dto.getMemModelId() != null) {
existingEntity.setMemModelId(dto.getMemModelId());
}
@@ -87,6 +87,7 @@ public class ConfigServiceImpl implements ConfigService {
null,
null,
null,
null,
agent.getVadModelId(),
agent.getAsrModelId(),
null,
@@ -135,15 +136,24 @@ public class ConfigServiceImpl implements ConfigService {
String voice = null;
String referenceAudio = null;
String referenceText = null;
String language = null;
TimbreDetailsVO timbre = timbreService.get(agent.getTtsVoiceId());
if (timbre != null) {
voice = timbre.getTtsVoice();
referenceAudio = timbre.getReferenceAudio();
referenceText = timbre.getReferenceText();
// 优先使用用户选择的语言,如果没有则使用音色支持的第一个语言
if (StringUtils.isNotBlank(agent.getTtsLanguage())) {
language = agent.getTtsLanguage();
} else if (StringUtils.isNotBlank(timbre.getLanguages())) {
language = timbre.getLanguages().split("")[0].trim();
}
} else {
VoiceCloneEntity voice_print = cloneVoiceService.selectById(agent.getTtsVoiceId());
if (voice_print != null) {
voice = voice_print.getVoiceId();
// 优先使用用户选择的语言,如果没有则使用默认值
language = StringUtils.isNotBlank(agent.getTtsLanguage()) ? agent.getTtsLanguage() : "普通话";
}
}
// 构建返回数据
@@ -208,6 +218,7 @@ public class ConfigServiceImpl implements ConfigService {
voice,
referenceAudio,
referenceText,
language,
agent.getVadModelId(),
agent.getAsrModelId(),
agent.getLlmModelId(),
@@ -385,6 +396,7 @@ public class ConfigServiceImpl implements ConfigService {
String voice,
String referenceAudio,
String referenceText,
String language,
String vadModelId,
String asrModelId,
String llmModelId,
@@ -423,6 +435,8 @@ public class ConfigServiceImpl implements ConfigService {
((Map<String, Object>) model.getConfigJson()).put("ref_audio", referenceAudio);
if (referenceText != null)
((Map<String, Object>) model.getConfigJson()).put("ref_text", referenceText);
if (language != null)
((Map<String, Object>) model.getConfigJson()).put("language", language);
// 火山引擎声音克隆需要替换resource_id
Map<String, Object> map = (Map<String, Object>) model.getConfigJson();
@@ -23,6 +23,9 @@ public class VoiceDTO implements Serializable {
@Schema(description = "音频播放地址")
private String voiceDemo;
@Schema(description = "语言类型")
private String languages;
@Schema(description = "是否为克隆音色")
private Boolean isClone;
@@ -31,6 +34,7 @@ public class VoiceDTO implements Serializable {
this.id = id;
this.name = name;
this.voiceDemo = null;
this.languages = null;
this.isClone = false; // 默认不是克隆音色
}
@@ -39,6 +43,7 @@ public class VoiceDTO implements Serializable {
this.id = id;
this.name = name;
this.voiceDemo = voiceDemo;
this.languages = null;
this.isClone = false;
}
@@ -129,6 +129,7 @@ public class TimbreServiceImpl extends BaseServiceImpl<TimbreDao, TimbreEntity>
.map(entity -> {
VoiceDTO dto = new VoiceDTO(entity.getId(), entity.getName());
dto.setVoiceDemo(entity.getVoiceDemo());
dto.setLanguages(entity.getLanguages()); // 设置语言类型
dto.setIsClone(false); // 设置为普通音色
return dto;
})
@@ -146,6 +147,7 @@ public class TimbreServiceImpl extends BaseServiceImpl<TimbreDao, TimbreEntity>
voiceDTO.setName(MessageUtils.getMessage(ErrorCode.VOICE_CLONE_PREFIX) + entity.getName());
// 保留从数据库查询到的voiceDemo字段
voiceDTO.setVoiceDemo(entity.getVoiceDemo());
voiceDTO.setLanguages(entity.getLanguages());
voiceDTO.setIsClone(true); // 设置为克隆音色
redisUtils.set(RedisKeys.getTimbreNameById(voiceDTO.getId()), voiceDTO.getName(),
RedisUtils.NOT_EXPIRE);
@@ -11,4 +11,10 @@ SET languages = CASE
WHEN languages = '中文(粤语)及中英文混合' THEN '粤语、英语'
WHEN languages = '粤语及粤英混合' THEN '粤语、英语'
ELSE languages
END;
END;
-- 添加音色语言字段到 ai_agent 表
ALTER TABLE `ai_agent` ADD COLUMN `tts_language` VARCHAR(50) NULL COMMENT '音色语言' AFTER `tts_voice_id`;
-- 添加音色语言字段到 ai_agent_template 表
ALTER TABLE `ai_agent_template` ADD COLUMN `tts_language` VARCHAR(50) NULL COMMENT '音色语言' AFTER `tts_voice_id`;
@@ -16,6 +16,7 @@
<result column="llmModelId" property="llmModelId"/>
<result column="ttsModelId" property="ttsModelId"/>
<result column="ttsVoiceId" property="ttsVoiceId"/>
<result column="ttsLanguage" property="ttsLanguage"/>
<result column="memModelId" property="memModelId"/>
<result column="intentModelId" property="intentModelId"/>
@@ -45,6 +46,7 @@
a.vllm_model_id AS vllmModelId,
a.tts_model_id AS ttsModelId,
a.tts_voice_id AS ttsVoiceId,
a.tts_language AS ttsLanguage,
a.mem_model_id AS memModelId,
a.intent_model_id AS intentModelId,
COALESCE(