feat: tts节点

This commit is contained in:
stream 2025-09-26 17:15:53 +08:00
parent f60db6cd85
commit 9f324941d3
6 changed files with 97 additions and 1 deletions

View File

@ -119,3 +119,4 @@ api:
speech-to-text-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow speech-to-text-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/run_app_workflow
query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process query-result-url: https://aiagentplatform.cmft.com/api/proxy/api/v1/query_run_app_process
bge-vl: http://192.168.1.8:5000/search_similar bge-vl: http://192.168.1.8:5000/search_similar
generate_advanced_audio: http://192.168.0.19:8000/generate_advanced_audio

View File

@ -29,4 +29,9 @@ public class APIProperties {
private String queryResultUrl; private String queryResultUrl;
private String bgeVl; private String bgeVl;
/**
* 文本合成语音
*/
private String generateAdvancedAudio;
} }

View File

@ -1,5 +1,7 @@
package com.cmvr.common.exception; package com.cmvr.common.exception;
import cn.hutool.core.util.StrUtil;
/** /**
* 全局异常 * 全局异常
* *
@ -33,6 +35,11 @@ public class GlobalException extends RuntimeException
this.message = message; this.message = message;
} }
public GlobalException(String template, Object... params) {
this.message = StrUtil.format(template, params);
}
public String getDetailMessage() public String getDetailMessage()
{ {
return detailMessage; return detailMessage;

View File

@ -46,6 +46,7 @@ public enum ActionEnum {
// 大模型行为 // 大模型行为
// ---------------获取触控坐标--------------- // ---------------获取触控坐标---------------
TOUCH_COORDINATES("LLM", "TOUCH_COORDINATES", "获取触控坐标"), TOUCH_COORDINATES("LLM", "TOUCH_COORDINATES", "获取触控坐标"),
GENERATE_ADVANCED_AUDIO("LLM", "GENERATE_ADVANCED_AUDIO", "tts语音合成"),
// 语音交互 // 语音交互
// ---------------语料--------------- // ---------------语料---------------

View File

@ -0,0 +1,82 @@
package com.cmvr.test.flow.runtime.operator.llm;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.llm.config.APIProperties;
import com.cmvr.test.enums.ActionEnum;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
@RequiredArgsConstructor
public class LLMTTSOperateService implements LLMOperateService {
private final APIProperties apiProperties;
@Override
public boolean supports(ActionEnum action) {
return action.name().equals("GENERATE_ADVANCED_AUDIO");
}
@Override
public TaskNodeExecuteResult execute(TaskNodeExecuteMessage message) {
JSONObject inputParams = message.getInputParams();
String text = inputParams.getString("text");
JSONObject output = new JSONObject();
// 1. 构建请求体
Map<String, Object> body = new HashMap<>();
body.put("text", text);
body.put("dialect", "普通话");
body.put("timbre", "");
body.put("language", "中文");
body.put("tone", "中性");
// 2. 发送请求到语音合成服务
HttpResponse response = HttpRequest.post(apiProperties.getGenerateAdvancedAudio())
.header("Content-Type", "application/json")
.body(JSON.toJSONString(body))
.execute();
if (!response.isOk()) {
throw new GlobalException("音频生成失败,状态码: " + response.getStatus());
}
// 3. 获取音频数据
byte[] audioData = response.bodyBytes();
// 4. 生成本地文件路径
String filename = System.currentTimeMillis() + "_" + text + ".wav";
String saveDir = "C:\\Users\\11158\\Desktop\\iot";
File dir = new File(saveDir);
if (!dir.exists() && !dir.mkdirs()) {
throw new GlobalException("音频保存目录创建失败: " + saveDir);
}
File audioFile = FileUtil.writeBytes(audioData, new File(dir, filename));
log.info("音频生成成功,保存路径: {}", audioFile.getAbsolutePath());
// 5. 预留上传功能
// String fileUrl = fileUploadService.upload(audioFile);
// 先返回本地路径
output.put("localPath", audioFile.getAbsolutePath());
// output.put("url", fileUrl); // 上传后再返回 url
return TaskNodeExecuteResult.success(output);
}
}

View File

@ -138,7 +138,7 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
.eq(ViProject::getStatus, "0"); .eq(ViProject::getStatus, "0");
ViProject project = this.getOne(wrapperProject); ViProject project = this.getOne(wrapperProject);
if (ObjUtil.isEmpty(project)) { if (ObjUtil.isEmpty(project)) {
throw new GlobalException(StrUtil.format("项目id为 [{}] 的任务不存在或未执行!", projectId)); throw new GlobalException("项目id为 [{}] 的任务不存在或未执行!", projectId);
} }
LambdaQueryWrapper<TeTaskInst> wrapper = Wrappers.lambdaQuery(TeTaskInst.class); LambdaQueryWrapper<TeTaskInst> wrapper = Wrappers.lambdaQuery(TeTaskInst.class);
wrapper.eq(TeTaskInst::getTaskId, projectId) wrapper.eq(TeTaskInst::getTaskId, projectId)