TTS 返回语音优化
This commit is contained in:
@@ -144,8 +144,10 @@ public class ChatWebSocketHandler {
|
||||
log.info("3、开始进行AI回答时间:{}",System.currentTimeMillis()/1000);
|
||||
//持续返回数据流给客户端
|
||||
try {
|
||||
String resultOutPathUrl = RuoYiConfig.getProfile() + VOICE_STORAGE_RESULT_DIR + "110_"+resultFileName;
|
||||
handleVoice(resultPathUrl,resultOutPathUrl);
|
||||
//文件转换成文件流
|
||||
ByteBuffer outByteBuffer = convertFileToByteBuffer(resultPathUrl);
|
||||
ByteBuffer outByteBuffer = convertFileToByteBuffer(resultOutPathUrl);
|
||||
//发送文件流数据
|
||||
session.getBasicRemote().sendBinary(outByteBuffer);
|
||||
// 发送响应确认
|
||||
@@ -404,6 +406,50 @@ public class ChatWebSocketHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleVoice(String inputPath,String outputPath){
|
||||
double trimMs = 270; // 要去掉的尾部时长(毫秒)
|
||||
|
||||
try {
|
||||
// 1. 解析音频格式和总长度
|
||||
AudioInputStream audioIn = AudioSystem.getAudioInputStream(new File(inputPath));
|
||||
AudioFormat format = audioIn.getFormat();
|
||||
long totalBytes = audioIn.getFrameLength() * format.getFrameSize(); // 总字节数
|
||||
|
||||
// 2. 计算300毫秒对应的字节数
|
||||
float sampleRate = format.getSampleRate(); // 采样率(Hz)
|
||||
int frameSize = format.getFrameSize(); // 每帧字节数(位深/8 * 声道数)
|
||||
double trimSeconds = trimMs / 1000.0; // 转换为秒
|
||||
long trimBytes = (long) (sampleRate * trimSeconds * frameSize); // 要去掉的字节数
|
||||
|
||||
// 3. 计算需要保留的字节数(避免负数)
|
||||
long keepBytes = Math.max(0, totalBytes - trimBytes);
|
||||
if (keepBytes == 0) {
|
||||
System.out.println("音频长度小于300毫秒,无法截断");
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 读取并保留前半部分(去掉最后300毫秒)
|
||||
try (InputStream in = new FileInputStream(inputPath);
|
||||
OutputStream out = new FileOutputStream(outputPath)) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
long totalRead = 0;
|
||||
int bytesRead;
|
||||
|
||||
while (totalRead < keepBytes && (bytesRead = in.read(buffer)) != -1) {
|
||||
long remaining = keepBytes - totalRead;
|
||||
int writeBytes = (remaining < bytesRead) ? (int) remaining : bytesRead;
|
||||
out.write(buffer, 0, writeBytes);
|
||||
totalRead += writeBytes;
|
||||
}
|
||||
|
||||
System.out.println("处理完成,去掉了最后" + trimMs + "毫秒,保留了" + totalRead + "字节");
|
||||
}
|
||||
|
||||
} catch (UnsupportedAudioFileException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public class AiCommonController extends BaseController
|
||||
@GetMapping("/handleTextToVice")
|
||||
public AjaxResult handleTextToVice()
|
||||
{
|
||||
elevenLabsClient.handleTextToVoice("我只是测试的文本转换成语音","/Users/wangxiangshun/Desktop/临时文件/output1112.mp3");
|
||||
elevenLabsClient.handleTextToVoice("Hello ! I can","/Users/wangxiangshun/Desktop/临时文件/output1112.wav");
|
||||
return success();
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,8 @@ verification:
|
||||
# 文本转语音
|
||||
elevenLabs:
|
||||
baseUrl: https://api.elevenlabs.io/v1
|
||||
apiKey: sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812
|
||||
# apiKey: sk_5240d8f56cb1eb5225fffcf903f62479884d1af5b3de6812
|
||||
apiKey: sk_88f5a560e1bbde0e5b8b6b6eb1812163a98bfb98554acbec
|
||||
modelId: eleven_turbo_v2_5
|
||||
# 语音转文本
|
||||
whisper:
|
||||
|
||||
@@ -115,21 +115,22 @@ public class OpenAiStreamClient {
|
||||
.getJSONObject("delta")
|
||||
.getStr("content");
|
||||
|
||||
if (content != null && !content.isEmpty()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// if (content != null && !content.isEmpty()) {
|
||||
// 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);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
listener.onMessage(content);
|
||||
} catch (Exception e) {
|
||||
listener.onError(new IOException("Parse error: " + e.getMessage()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user