|
@@ -1,16 +1,25 @@
|
|
package com.fs.fastgptApi.util;
|
|
package com.fs.fastgptApi.util;
|
|
|
|
|
|
|
|
+import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.fs.common.exception.ServiceException;
|
|
import com.fs.common.exception.ServiceException;
|
|
import com.fs.common.exception.base.BaseException;
|
|
import com.fs.common.exception.base.BaseException;
|
|
|
|
+import com.fs.config.ai.AiHostProper;
|
|
|
|
+import com.fs.fastGpt.domain.FastgptChatVoiceHomo;
|
|
|
|
+import com.fs.fastGpt.service.IFastGptChatMsgService;
|
|
import com.fs.fastgptApi.vo.AudioVO;
|
|
import com.fs.fastgptApi.vo.AudioVO;
|
|
import com.fs.system.oss.CloudStorageService;
|
|
import com.fs.system.oss.CloudStorageService;
|
|
import com.fs.system.oss.OSSFactory;
|
|
import com.fs.system.oss.OSSFactory;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
import org.apache.http.HttpEntity;
|
|
import org.apache.http.HttpEntity;
|
|
import org.apache.http.HttpResponse;
|
|
import org.apache.http.HttpResponse;
|
|
|
|
+import org.apache.http.HttpStatus;
|
|
import org.apache.http.client.methods.HttpGet;
|
|
import org.apache.http.client.methods.HttpGet;
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
import org.apache.http.impl.client.HttpClients;
|
|
import org.apache.http.impl.client.HttpClients;
|
|
import org.apache.http.util.EntityUtils;
|
|
import org.apache.http.util.EntityUtils;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
|
|
import javax.sound.sampled.AudioInputStream;
|
|
import javax.sound.sampled.AudioInputStream;
|
|
import javax.sound.sampled.AudioSystem;
|
|
import javax.sound.sampled.AudioSystem;
|
|
@@ -20,16 +29,83 @@ import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
import java.net.URL;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Files;
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.Date;
|
|
|
|
-import java.util.List;
|
|
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
+@Slf4j
|
|
|
|
+@Component
|
|
public class AudioUtils {
|
|
public class AudioUtils {
|
|
|
|
+
|
|
|
|
+ private static AiHostProper staticAiHostProper;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ public void setAiHostProper(AiHostProper service) {
|
|
|
|
+ AudioUtils.staticAiHostProper = service;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 工具地址
|
|
* 工具地址
|
|
**/
|
|
**/
|
|
static String path = "c:\\";
|
|
static String path = "c:\\";
|
|
static String destinationDir = "c:\\hook\\";
|
|
static String destinationDir = "c:\\hook\\";
|
|
|
|
+ public static AudioVO createVoiceUrl(Long id,String userVoiceUrl){
|
|
|
|
+ String fileUrl = staticAiHostProper.getVoiceApi() + "/app/common/createVoiceUrl?id=" + id + "&userVoiceUrl=" + userVoiceUrl;
|
|
|
|
+
|
|
|
|
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
|
|
+ HttpGet httpGet = new HttpGet(fileUrl);
|
|
|
|
+ HttpResponse response = httpClient.execute(httpGet);
|
|
|
|
+
|
|
|
|
+ // 检查响应状态码
|
|
|
|
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
|
|
|
+ String responseBody = EntityUtils.toString(response.getEntity());
|
|
|
|
+
|
|
|
|
+ // 使用JSON工具解析响应
|
|
|
|
+ ObjectMapper mapper = new ObjectMapper();
|
|
|
|
+ JsonNode jsonNode = mapper.readTree(responseBody);
|
|
|
|
+ JsonNode dataNode = jsonNode.get("data");
|
|
|
|
+ return mapper.treeToValue(dataNode, AudioVO.class);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static AudioVO createUserUrlAndUrl(List<FastgptChatVoiceHomo> homos,Long id,String voiceTxt){
|
|
|
|
+ String voiceHomo = voiceHomo(homos,voiceTxt);
|
|
|
|
+ String fileUrl = staticAiHostProper.getVoiceApi() + "/app/common/createUserUrlAndUrl?id=" + id + "&voiceTxt=" + voiceHomo;
|
|
|
|
+
|
|
|
|
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
|
|
+ HttpGet httpGet = new HttpGet(fileUrl);
|
|
|
|
+ HttpResponse response = httpClient.execute(httpGet);
|
|
|
|
+
|
|
|
|
+ // 检查响应状态码
|
|
|
|
+ if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
|
|
|
|
+ String responseBody = EntityUtils.toString(response.getEntity());
|
|
|
|
+
|
|
|
|
+ // 使用JSON工具解析响应
|
|
|
|
+ ObjectMapper mapper = new ObjectMapper();
|
|
|
|
+ JsonNode jsonNode = mapper.readTree(responseBody);
|
|
|
|
+ JsonNode dataNode = jsonNode.get("data");
|
|
|
|
+ return mapper.treeToValue(dataNode, AudioVO.class);
|
|
|
|
+ }
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String voiceHomo(List<FastgptChatVoiceHomo> homos,String content){
|
|
|
|
+ for (FastgptChatVoiceHomo homo : homos) {
|
|
|
|
+ if (content.contains(homo.getContent())) {
|
|
|
|
+ // 如果包含目标字段,则替换
|
|
|
|
+ content= content.replace(homo.getContent(), homo.getChangeCount());
|
|
|
|
+ } else {
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return content;
|
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
/**
|
|
* 从网络 URL 转换 MP3/WAV到SILk格式
|
|
* 从网络 URL 转换 MP3/WAV到SILk格式
|
|
@@ -69,13 +145,39 @@ public class AudioUtils {
|
|
if (tempFile == null) {
|
|
if (tempFile == null) {
|
|
throw new ServiceException("下载文件失败");
|
|
throw new ServiceException("下载文件失败");
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
Integer durations = getDurations(destinationDir+tempFile);
|
|
Integer durations = getDurations(destinationDir+tempFile);
|
|
String silkUrl = transferAudioSilk(destinationDir, tempFile, isSource);
|
|
String silkUrl = transferAudioSilk(destinationDir, tempFile, isSource);
|
|
AudioVO audioVO = new AudioVO();
|
|
AudioVO audioVO = new AudioVO();
|
|
audioVO.setDuration(durations);
|
|
audioVO.setDuration(durations);
|
|
audioVO.setUrl(silkUrl);
|
|
audioVO.setUrl(silkUrl);
|
|
|
|
+ File wavFile = new File(destinationDir+tempFile);
|
|
|
|
+ if (wavFile.exists()) {
|
|
|
|
+ wavFile.delete();
|
|
|
|
+ }
|
|
|
|
+ // 调用原来的转换方法
|
|
|
|
+ return audioVO;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static AudioVO transferCompanyIdAudioSilkFromText(String voiceText,Long companyUserId, boolean isSource) {
|
|
|
|
+ try {
|
|
|
|
+ // 下载文件到本地临时路径
|
|
|
|
+ String tempFile = downloadFileFromText(voiceText,companyUserId);
|
|
|
|
+ if (tempFile == null) {
|
|
|
|
+ throw new ServiceException("下载文件失败");
|
|
|
|
+ }
|
|
|
|
+ Integer durations = getDurations(destinationDir+tempFile);
|
|
|
|
+ AudioVO audioVO = transferCompanyAudioSilk(destinationDir, tempFile, isSource);
|
|
|
|
+
|
|
|
|
+ audioVO.setDuration(durations);
|
|
|
|
+
|
|
|
|
+ File wavFile = new File(destinationDir+tempFile);
|
|
|
|
+ if (wavFile.exists()) {
|
|
|
|
+ wavFile.delete();
|
|
|
|
+ }
|
|
// 调用原来的转换方法
|
|
// 调用原来的转换方法
|
|
return audioVO;
|
|
return audioVO;
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
@@ -84,6 +186,7 @@ public class AudioUtils {
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
public static AudioVO transferAudioSilkFromTextNew(String Text,Long id, boolean isSource) {
|
|
public static AudioVO transferAudioSilkFromTextNew(String Text,Long id, boolean isSource) {
|
|
try {
|
|
try {
|
|
// 下载文件到本地临时路径
|
|
// 下载文件到本地临时路径
|
|
@@ -132,7 +235,7 @@ public class AudioUtils {
|
|
path + "ffmpeg.exe",
|
|
path + "ffmpeg.exe",
|
|
"-i", audioFilePath,WAVPath
|
|
"-i", audioFilePath,WAVPath
|
|
};
|
|
};
|
|
- System.out.println(command[2]);
|
|
|
|
|
|
+ log.info(command[2]);
|
|
// 启动进程执行命令
|
|
// 启动进程执行命令
|
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
|
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
|
processBuilder.redirectErrorStream(true); // 合并标准输出和错误输出
|
|
processBuilder.redirectErrorStream(true); // 合并标准输出和错误输出
|
|
@@ -167,11 +270,11 @@ public class AudioUtils {
|
|
while ((line = reader.readLine()) != null) {
|
|
while ((line = reader.readLine()) != null) {
|
|
// 打印或解析输出信息
|
|
// 打印或解析输出信息
|
|
if (line.contains("Duration")) {
|
|
if (line.contains("Duration")) {
|
|
- System.out.println(line);
|
|
|
|
|
|
+ log.info(line);
|
|
// 查找并解析时长信息
|
|
// 查找并解析时长信息
|
|
String duration = line.substring(line.indexOf("Duration: ") +10, line.indexOf(","));
|
|
String duration = line.substring(line.indexOf("Duration: ") +10, line.indexOf(","));
|
|
int i = convertDurationToSeconds(duration);
|
|
int i = convertDurationToSeconds(duration);
|
|
- System.out.println("音频时长: " + i);
|
|
|
|
|
|
+ log.info("音频时长: " + i);
|
|
durations=i;
|
|
durations=i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -198,7 +301,7 @@ public class AudioUtils {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
/**
|
|
-// * MP3/WAV转SILk格式
|
|
|
|
|
|
+ // * MP3/WAV转SILk格式
|
|
*
|
|
*
|
|
* @param path 文件路径 例:D:\\file\\
|
|
* @param path 文件路径 例:D:\\file\\
|
|
* @param name 文件名称 例:audio.mp3/audio.wav
|
|
* @param name 文件名称 例:audio.mp3/audio.wav
|
|
@@ -219,16 +322,17 @@ public class AudioUtils {
|
|
throw new Exception("文件不存在!");
|
|
throw new Exception("文件不存在!");
|
|
}
|
|
}
|
|
// 文件名时拼接
|
|
// 文件名时拼接
|
|
- SimpleDateFormat ttime = new SimpleDateFormat("yyyyMMddhhmmss");
|
|
|
|
- String time = ttime.format(new Date());
|
|
|
|
|
|
+ // 使用 UUID + 临时目录隔离
|
|
|
|
+ File tempDir = Files.createTempDirectory("audioSilk_").toFile();
|
|
|
|
+ String uuid = UUID.randomUUID().toString().replace("-", "");
|
|
// 导出的pcm格式路径
|
|
// 导出的pcm格式路径
|
|
- String pcmPath = path + "PCM_" + time + ".pcm";
|
|
|
|
|
|
+ String pcmPath = tempDir.getAbsolutePath() + File.separator + "PCM_" + uuid + ".pcm";
|
|
// 先将mp3/wav转换成pcm格式
|
|
// 先将mp3/wav转换成pcm格式
|
|
- transferAudioPcm(filePath, pcmPath);
|
|
|
|
|
|
+ transferAudioPcmSecond(filePath, pcmPath);
|
|
// 导出的silk格式路径
|
|
// 导出的silk格式路径
|
|
- String silkPath = path + "SILK_" + time + ".silk";
|
|
|
|
|
|
+ String silkPath = tempDir.getAbsolutePath() + File.separator + "SILK_" + uuid + ".silk";
|
|
// 转换成silk格式
|
|
// 转换成silk格式
|
|
- transferPcmSilk(pcmPath, silkPath);
|
|
|
|
|
|
+ transferPcmSilkSecond(pcmPath, silkPath);
|
|
// 删除pcm文件
|
|
// 删除pcm文件
|
|
File pcmFile = new File(pcmPath);
|
|
File pcmFile = new File(pcmPath);
|
|
if (pcmFile.exists()) {
|
|
if (pcmFile.exists()) {
|
|
@@ -252,12 +356,86 @@ public class AudioUtils {
|
|
if (silkFile.exists()) {
|
|
if (silkFile.exists()) {
|
|
silkFile.delete();
|
|
silkFile.delete();
|
|
}
|
|
}
|
|
|
|
+ //最后删除文件夹
|
|
|
|
+ if (tempDir.exists()) {
|
|
|
|
+ tempDir.delete();
|
|
|
|
+ }
|
|
return silkUrl;
|
|
return silkUrl;
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ public static AudioVO transferCompanyAudioSilk(String path, String name, boolean isSource) {
|
|
|
|
+ AudioVO audioVO = new AudioVO();
|
|
|
|
+ try {
|
|
|
|
+ // 判断后缀格式
|
|
|
|
+ String suffix = name.split("\\.")[1];
|
|
|
|
+ if (!suffix.toLowerCase().equals("mp3") && !suffix.toLowerCase().equals("wav")) {
|
|
|
|
+ throw new ServiceException("文件格式必须是mp3/wav");
|
|
|
|
+ }
|
|
|
|
+ String filePath = path + name;
|
|
|
|
+ File file = new File(filePath);
|
|
|
|
+ if (!file.exists()) {
|
|
|
|
+ throw new Exception("文件不存在!");
|
|
|
|
+ }
|
|
|
|
+ File wavFile = new File(filePath);
|
|
|
|
+ //上传silk文件
|
|
|
|
+ String wavPathSuffix = filePath.split("\\.")[1];
|
|
|
|
+ CloudStorageService wavStorage = OSSFactory.build();
|
|
|
|
+ byte[] wavBytes = Files.readAllBytes(wavFile.toPath());
|
|
|
|
+ String wavUrl = wavStorage.uploadSuffix(wavBytes, "."+wavPathSuffix);
|
|
|
|
+ audioVO.setWavUrl(wavUrl);
|
|
|
|
+
|
|
|
|
+ // 文件名时拼接
|
|
|
|
+ // 使用 UUID + 临时目录隔离
|
|
|
|
+ File tempDir = Files.createTempDirectory("audio_").toFile();
|
|
|
|
+ String uuid = UUID.randomUUID().toString().replace("-", "");
|
|
|
|
+ // 导出的pcm格式路径
|
|
|
|
+ String pcmPath = tempDir.getAbsolutePath() + File.separator + "PCM_" + uuid + ".pcm";
|
|
|
|
+ // 先将mp3/wav转换成pcm格式
|
|
|
|
+ transferAudioPcmSecond(filePath, pcmPath);
|
|
|
|
+ // 导出的silk格式路径
|
|
|
|
+ String silkPath = tempDir.getAbsolutePath() + File.separator + "SILK_" + uuid + ".silk";
|
|
|
|
+ // 转换成silk格式
|
|
|
|
+ transferPcmSilkSecond(pcmPath, silkPath);
|
|
|
|
+ // 删除pcm文件
|
|
|
|
+ File pcmFile = new File(pcmPath);
|
|
|
|
+ if (pcmFile.exists()) {
|
|
|
|
+ pcmFile.delete();
|
|
|
|
+ }
|
|
|
|
+ if (isSource) {
|
|
|
|
+ File audioFile = new File(filePath);
|
|
|
|
+
|
|
|
|
+ if (audioFile.exists()) {
|
|
|
|
+ audioFile.delete();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ File silkFile = new File(silkPath);
|
|
|
|
+ //上传silk文件
|
|
|
|
+ String silkPathSuffix = silkPath.split("\\.")[1];
|
|
|
|
+ CloudStorageService storage = OSSFactory.build();
|
|
|
|
+ byte[] fileBytes = Files.readAllBytes(silkFile.toPath());
|
|
|
|
+ String silkUrl = storage.uploadSuffix(fileBytes, "."+silkPathSuffix);
|
|
|
|
+
|
|
|
|
+ if (silkFile.exists()) {
|
|
|
|
+ silkFile.delete();
|
|
|
|
+ }
|
|
|
|
+ //最后删除文件夹
|
|
|
|
+ if (tempDir.exists()) {
|
|
|
|
+ tempDir.delete();
|
|
|
|
+ }
|
|
|
|
+ audioVO.setUrl(silkUrl);
|
|
|
|
+ return audioVO;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return audioVO;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
public static String transferAudioSilkNew(String path, String name, boolean isSource) {
|
|
public static String transferAudioSilkNew(String path, String name, boolean isSource) {
|
|
try {
|
|
try {
|
|
// 判断后缀格式
|
|
// 判断后缀格式
|
|
@@ -334,7 +512,7 @@ public class AudioUtils {
|
|
* @param target
|
|
* @param target
|
|
*/
|
|
*/
|
|
private static void transferAudioPcm(String fpath, String target) {
|
|
private static void transferAudioPcm(String fpath, String target) {
|
|
- System.out.println("pcm地址"+fpath);
|
|
|
|
|
|
+ log.info("pcm地址"+fpath);
|
|
List<String> commend = new ArrayList<String>();
|
|
List<String> commend = new ArrayList<String>();
|
|
commend.add("cmd");
|
|
commend.add("cmd");
|
|
commend.add("/c");
|
|
commend.add("/c");
|
|
@@ -354,7 +532,7 @@ public class AudioUtils {
|
|
try {
|
|
try {
|
|
ProcessBuilder builder = new ProcessBuilder();
|
|
ProcessBuilder builder = new ProcessBuilder();
|
|
builder.command(commend);
|
|
builder.command(commend);
|
|
- // builder.inheritIO();
|
|
|
|
|
|
+ // builder.inheritIO();
|
|
Process p = builder.start();
|
|
Process p = builder.start();
|
|
p.waitFor();
|
|
p.waitFor();
|
|
p.destroy();
|
|
p.destroy();
|
|
@@ -363,6 +541,66 @@ public class AudioUtils {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * mp3/wav 通用
|
|
|
|
+ * @param fpath
|
|
|
|
+ * @param target
|
|
|
|
+ */
|
|
|
|
+ private static void transferAudioPcmSecond(String fpath, String target) {
|
|
|
|
+ Process process = null;
|
|
|
|
+ try {
|
|
|
|
+ List<String> command = new ArrayList<String>();
|
|
|
|
+ command.add(path + "ffmpeg.exe");
|
|
|
|
+ command.add("-y");
|
|
|
|
+ command.add("-i");
|
|
|
|
+ command.add(fpath);
|
|
|
|
+ command.add("-f");
|
|
|
|
+ command.add("s16le");
|
|
|
|
+ command.add("-ar");
|
|
|
|
+ command.add("24000");
|
|
|
|
+ command.add("-ac");
|
|
|
|
+ command.add("1");
|
|
|
|
+ command.add(target);
|
|
|
|
+
|
|
|
|
+ ProcessBuilder builder = new ProcessBuilder();
|
|
|
|
+ builder.command(command);
|
|
|
|
+ builder.redirectErrorStream(true);
|
|
|
|
+
|
|
|
|
+ process = builder.start();
|
|
|
|
+
|
|
|
|
+ // 添加超时机制,避免进程无限挂起
|
|
|
|
+ boolean finished = process.waitFor(10, TimeUnit.SECONDS);
|
|
|
|
+ if (!finished) {
|
|
|
|
+ process.destroyForcibly();
|
|
|
|
+ throw new ServiceException("PCM转换超时");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int exitCode = process.exitValue();
|
|
|
|
+ if (exitCode != 0) {
|
|
|
|
+ throw new ServiceException("PCM转换失败,退出码:" + exitCode);
|
|
|
|
+ }
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
|
+ throw new ServiceException("PCM转换被中断"+ e);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new ServiceException("PCM转换IO异常:" + e.getMessage() + e);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new ServiceException("PCM转换异常:" + e.getMessage() + e);
|
|
|
|
+ } finally {
|
|
|
|
+ if (process != null) {
|
|
|
|
+ try {
|
|
|
|
+ process.destroy();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ // 记录但不抛出异常,避免掩盖主异常
|
|
|
|
+ System.err.println("销毁进程时出错:" + e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
/**
|
|
/**
|
|
* silk_v3_encoder.exe,转成Silk格式
|
|
* silk_v3_encoder.exe,转成Silk格式
|
|
@@ -412,6 +650,52 @@ public class AudioUtils {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 解决语音较长时转换不完全的问题
|
|
|
|
+ * @param pcmPath
|
|
|
|
+ * @param target
|
|
|
|
+ */
|
|
|
|
+ public static void transferPcmSilkSecond(String pcmPath, String target) {
|
|
|
|
+ Process process = null;
|
|
|
|
+ try {
|
|
|
|
+ // 使用 ProcessBuilder 替代 Runtime.exec 提高可靠性
|
|
|
|
+ List<String> command = new ArrayList<>();
|
|
|
|
+ command.add("cmd");
|
|
|
|
+ command.add("/c");
|
|
|
|
+ command.add("start");
|
|
|
|
+ command.add("/wait"); // 等待程序执行完毕才退出
|
|
|
|
+ command.add(path + "silk_v3_encoder.exe");
|
|
|
|
+ command.add(pcmPath);
|
|
|
|
+ command.add(target);
|
|
|
|
+ command.add("-tencent");
|
|
|
|
+
|
|
|
|
+ ProcessBuilder builder = new ProcessBuilder(command);
|
|
|
|
+ builder.redirectErrorStream(true); // 合并标准输出和错误输出
|
|
|
|
+
|
|
|
|
+ process = builder.start();
|
|
|
|
+
|
|
|
|
+ // 可选:读取输出以确认执行状态
|
|
|
|
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
|
|
|
+ String line;
|
|
|
|
+ while ((line = reader.readLine()) != null) {
|
|
|
|
+ log.info(line); // 打印日志便于调试
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int exitCode = process.waitFor(); // 等待执行完成
|
|
|
|
+ if (exitCode != 0) {
|
|
|
|
+ System.err.println("silk_v3_encoder exited with code: " + exitCode);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } finally {
|
|
|
|
+ if (process != null) {
|
|
|
|
+ process.destroy();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
public static void transferPcmSilkNew(String pcmPath, String target) {
|
|
public static void transferPcmSilkNew(String pcmPath, String target) {
|
|
Process process = null;
|
|
Process process = null;
|
|
try {
|
|
try {
|
|
@@ -446,6 +730,8 @@ public class AudioUtils {
|
|
// 创建 HTTP 连接
|
|
// 创建 HTTP 连接
|
|
URL url = new URL(fileUrl);
|
|
URL url = new URL(fileUrl);
|
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
|
|
+ // 设置Referer请求头
|
|
|
|
+ connection.setRequestProperty("Referer", "cos.his.cdwjyyh.com");
|
|
connection.setRequestMethod("GET");
|
|
connection.setRequestMethod("GET");
|
|
connection.connect();
|
|
connection.connect();
|
|
|
|
|
|
@@ -458,12 +744,14 @@ public class AudioUtils {
|
|
inputStream = connection.getInputStream();
|
|
inputStream = connection.getInputStream();
|
|
|
|
|
|
// 创建临时文件,并指定存放地址
|
|
// 创建临时文件,并指定存放地址
|
|
- String tempFileName = "temp_" + System.currentTimeMillis() + "_" + getFileExtension(fileUrl);
|
|
|
|
|
|
+ String tempFileName = "temp_" + UUID.randomUUID() + "_" + getFileExtension(fileUrl);
|
|
File destinationDirectory = new File(destinationDir);
|
|
File destinationDirectory = new File(destinationDir);
|
|
|
|
|
|
- // 确保目标目录存在
|
|
|
|
- if (!destinationDirectory.exists()) {
|
|
|
|
- destinationDirectory.mkdirs();
|
|
|
|
|
|
+ // 参照 transferAudioSilk 方法,同步确保目录创建的线程安全
|
|
|
|
+ synchronized (AudioUtils.class) {
|
|
|
|
+ if (!destinationDirectory.exists()) {
|
|
|
|
+ destinationDirectory.mkdirs();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
// 将文件保存到指定路径
|
|
// 将文件保存到指定路径
|
|
@@ -501,13 +789,13 @@ public class AudioUtils {
|
|
.replaceAll("[a-zA-Z]", "")
|
|
.replaceAll("[a-zA-Z]", "")
|
|
.replaceAll("\\s", "");
|
|
.replaceAll("\\s", "");
|
|
try {
|
|
try {
|
|
- String fileUrl = "http://118.24.209.192:9881/?text="+text+"&ref_audio=./参考音频/companyUser"+userId+".wav&ref_text=在这片神奇的森林里,小鸟轻快地唱着歌,仿佛在诉说着春天的故事。"; // 替换为要下载的文件URL
|
|
|
|
|
|
+ String fileUrl = "http://127.0.0.1:9880/?text="+text+"&ref_audio=./参考音频/companyUser"+userId+".wav&ref_text=在这片神奇的森林里,小鸟轻快地唱着歌,仿佛在诉说着春天的故事。"; // 替换为要下载的文件URL
|
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
HttpGet httpGet = new HttpGet(fileUrl);
|
|
HttpGet httpGet = new HttpGet(fileUrl);
|
|
HttpResponse response = httpClient.execute(httpGet);
|
|
HttpResponse response = httpClient.execute(httpGet);
|
|
HttpEntity entity = response.getEntity();https://hf-mirror.com
|
|
HttpEntity entity = response.getEntity();https://hf-mirror.com
|
|
if (entity != null) {
|
|
if (entity != null) {
|
|
- inputStream = entity.getContent();
|
|
|
|
|
|
+ inputStream = entity.getContent();
|
|
byte[] fileBytes = convertInputStreamToByteArray(inputStream);
|
|
byte[] fileBytes = convertInputStreamToByteArray(inputStream);
|
|
// 对文件字节数组进行进一步处理
|
|
// 对文件字节数组进行进一步处理
|
|
String filePath = destinationDir+tempFileName; // 文件将被保存到 C 盘根目录下,文件名为 output_file.wav
|
|
String filePath = destinationDir+tempFileName; // 文件将被保存到 C 盘根目录下,文件名为 output_file.wav
|
|
@@ -548,13 +836,13 @@ public class AudioUtils {
|
|
.replaceAll("[a-zA-Z]", "")
|
|
.replaceAll("[a-zA-Z]", "")
|
|
.replaceAll("\\s", "");
|
|
.replaceAll("\\s", "");
|
|
try {
|
|
try {
|
|
- String fileUrl = "http://127.0.0.1:9881/?text="+text+"&ref_audio=./参考音频/companyUser"+userId+".wav&ref_text=在这片神奇的森林里,小鸟轻快地唱着歌,仿佛在诉说着春天的故事。"; // 替换为要下载的文件URL
|
|
|
|
|
|
+ String fileUrl = "http://127.0.0.1:9880/?text="+text+"&ref_audio=./参考音频/companyUser"+userId+".wav&ref_text=在这片神奇的森林里,小鸟轻快地唱着歌,仿佛在诉说着春天的故事。"; // 替换为要下载的文件URL
|
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
|
HttpGet httpGet = new HttpGet(fileUrl);
|
|
HttpGet httpGet = new HttpGet(fileUrl);
|
|
HttpResponse response = httpClient.execute(httpGet);
|
|
HttpResponse response = httpClient.execute(httpGet);
|
|
HttpEntity entity = response.getEntity();https://hf-mirror.com
|
|
HttpEntity entity = response.getEntity();https://hf-mirror.com
|
|
if (entity != null) {
|
|
if (entity != null) {
|
|
- inputStream = entity.getContent();
|
|
|
|
|
|
+ inputStream = entity.getContent();
|
|
byte[] fileBytes = convertInputStreamToByteArray(inputStream);
|
|
byte[] fileBytes = convertInputStreamToByteArray(inputStream);
|
|
// 对文件字节数组进行进一步处理
|
|
// 对文件字节数组进行进一步处理
|
|
String filePath = destinationDir+tempFileName; // 文件将被保存到 C 盘根目录下,文件名为 output_file.wav
|
|
String filePath = destinationDir+tempFileName; // 文件将被保存到 C 盘根目录下,文件名为 output_file.wav
|
|
@@ -655,7 +943,7 @@ public class AudioUtils {
|
|
Double v = clip.getMicrosecondLength() / 1000000D;
|
|
Double v = clip.getMicrosecondLength() / 1000000D;
|
|
return v;
|
|
return v;
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
- System.out.println("cuo");
|
|
|
|
|
|
+ log.info("cuo");
|
|
return null;
|
|
return null;
|
|
} finally {
|
|
} finally {
|
|
if(clip!=null){
|
|
if(clip!=null){
|
|
@@ -674,8 +962,5 @@ public class AudioUtils {
|
|
}
|
|
}
|
|
return byteOutput.toByteArray();
|
|
return byteOutput.toByteArray();
|
|
}
|
|
}
|
|
- // 省略其他方法的实现
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
|
|
}
|
|
}
|