TTS 返回语音优化

This commit is contained in:
2025-10-19 17:01:13 +08:00
parent a75d2dd985
commit a3ef5d1959
3 changed files with 26 additions and 45 deletions

View File

@@ -144,11 +144,6 @@ public class ChatWebSocketHandler {
log.info("3、开始进行AI回答时间:{}",System.currentTimeMillis()/1000); log.info("3、开始进行AI回答时间:{}",System.currentTimeMillis()/1000);
//持续返回数据流给客户端 //持续返回数据流给客户端
try { try {
File inputFile = new File(resultPathUrl);
File outputFile = new File(resultPathUrl);
// 设置去除尾部的秒数
float removeSeconds = 0.25f; // 去除最后5秒
trimEndByTime(inputFile, outputFile, removeSeconds);
//文件转换成文件流 //文件转换成文件流
ByteBuffer outByteBuffer = convertFileToByteBuffer(resultPathUrl); ByteBuffer outByteBuffer = convertFileToByteBuffer(resultPathUrl);
//发送文件流数据 //发送文件流数据
@@ -410,44 +405,5 @@ public class ChatWebSocketHandler {
} }
// 裁剪音频文件,去除最后多少秒
public void trimEndByTime(File inputFile, File outputFile, float removeSeconds) {
try {
// 获取音频输入流
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(inputFile);
AudioFormat format = audioInputStream.getFormat();
// 获取音频文件的总帧数
long totalFrames = audioInputStream.getFrameLength();
// 计算音频文件的总时长(秒)
float totalDuration = totalFrames / format.getSampleRate();
// 计算新的结束位置(去除指定的时间后)
long newEndFrame = (long) ((totalDuration - removeSeconds) * format.getSampleRate());
// 确保裁剪的结束帧在合理范围内
if (newEndFrame < 0) {
System.out.println("去除的时间超过了音频的总时长");
return;
}
// 创建一个新的输入流,裁剪音频数据
AudioInputStream trimmedStream = new AudioInputStream(
audioInputStream,
format,
newEndFrame
);
// 创建新的文件并保存裁剪后的音频
AudioSystem.write(trimmedStream, AudioFileFormat.Type.WAVE, outputFile);
System.out.println("裁剪后的音频已保存到: " + outputFile.getAbsolutePath());
audioInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
} }

View File

@@ -169,6 +169,7 @@
<groupId>org.java-websocket</groupId> <groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId> <artifactId>Java-WebSocket</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tomcat.embed</groupId> <groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId> <artifactId>tomcat-embed-websocket</artifactId>

View File

@@ -1,5 +1,6 @@
package com.vetti.common.ai.gpt; package com.vetti.common.ai.gpt;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject; import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.vetti.common.ai.gpt.service.OpenAiStreamListenerService; import com.vetti.common.ai.gpt.service.OpenAiStreamListenerService;
@@ -9,7 +10,9 @@ import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@@ -30,6 +33,12 @@ public class OpenAiStreamClient {
@Value("${chatGpt.role}") @Value("${chatGpt.role}")
private String role; private String role;
// 定义作为分割点的标点符号集合
private final Set<Character> punctuationSet = new HashSet<>() {{
add('。'); add(''); add(''); add(''); // 中文标点
add('.'); add('?'); add('!'); add(';'); // 英文标点
}};
/** /**
* 发送流式请求 * 发送流式请求
* *
@@ -42,6 +51,9 @@ public class OpenAiStreamClient {
.readTimeout(60, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS)
.build(); .build();
// 文本缓冲区
StringBuffer bufferStr = new StringBuffer();
// 构建请求参数 // 构建请求参数
Map<String, Object> requestBody = new HashMap<>(); Map<String, Object> requestBody = new HashMap<>();
requestBody.put("model", model); requestBody.put("model", model);
@@ -104,7 +116,19 @@ public class OpenAiStreamClient {
.getStr("content"); .getStr("content");
if (content != null && !content.isEmpty()) { if (content != null && !content.isEmpty()) {
listener.onMessage(content); if(punctuationSet.contains(content)){
//说明有标点啦,直接返回
bufferStr.append(content);
listener.onMessage(bufferStr.toString());
}else{
//加入缓冲区
if(StrUtil.isEmpty(bufferStr.toString())){
bufferStr.append(content);
}else {
bufferStr.append(" ").append(content);
}
}
} }
} catch (Exception e) { } catch (Exception e) {
listener.onError(new IOException("Parse error: " + e.getMessage())); listener.onError(new IOException("Parse error: " + e.getMessage()));