语音文件优化
This commit is contained in:
parent
a814c92060
commit
81e1aa081a
@ -10,7 +10,6 @@ import club.joylink.rtss.services.*;
|
||||
import club.joylink.rtss.services.script.IScriptService;
|
||||
import club.joylink.rtss.services.script.IScriptSimulationService;
|
||||
import club.joylink.rtss.services.simulation.ProjectSimulationService;
|
||||
import club.joylink.rtss.services.voice.IVoiceService;
|
||||
import club.joylink.rtss.services.voice.IVoiceTrainingService;
|
||||
import club.joylink.rtss.simulation.cbtc.ATS.ATSMessageCollectAndDispatcher;
|
||||
import club.joylink.rtss.simulation.cbtc.GroupSimulationCache;
|
||||
@ -24,6 +23,7 @@ import club.joylink.rtss.simulation.cbtc.exception.SimulationException;
|
||||
import club.joylink.rtss.simulation.cbtc.exception.SimulationExceptionType;
|
||||
import club.joylink.rtss.simulation.cbtc.script.ScriptActionBO;
|
||||
import club.joylink.rtss.simulation.cbtc.script.ScriptBO;
|
||||
import club.joylink.rtss.util.VoiceFileUtils;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.LoginUserInfoVO;
|
||||
import club.joylink.rtss.vo.client.PageVO;
|
||||
@ -44,7 +44,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
@ -101,9 +100,6 @@ public class CompetitionPracticalService implements ICompetitionPracticalService
|
||||
@Autowired
|
||||
private CompetitionVoiceRecordDAO competitionVoiceRecordDAO;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private IVoiceTrainingService iVoiceTrainingService;
|
||||
|
||||
@ -468,7 +464,7 @@ public class CompetitionPracticalService implements ICompetitionPracticalService
|
||||
|
||||
@Override
|
||||
public CompetitionVoiceRecordVO voiceRecord(Long competitionId, Long cmdEvaRuleId, String actionId, MultipartFile file, AccountVO user) {
|
||||
String filePath = IVoiceService.handleAndSaveFile(file);
|
||||
String filePath = VoiceFileUtils.saveFile(file);
|
||||
CompetitionVoiceRecord voiceRecord = new CompetitionVoiceRecord();
|
||||
voiceRecord.setUserId(user.getId());
|
||||
voiceRecord.setCompetitionId(competitionId);
|
||||
@ -484,7 +480,7 @@ public class CompetitionPracticalService implements ICompetitionPracticalService
|
||||
public CompetitionVoiceRecordVO updateVoiceRecord(Long recordId, MultipartFile file, AccountVO user) {
|
||||
CompetitionVoiceRecord record = getVoiceRecordEntity(recordId);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(record.getUserId(), user.getId());
|
||||
String filePath = IVoiceService.handleAndSaveFile(file);
|
||||
String filePath = VoiceFileUtils.saveFile(file);
|
||||
record.setFilePath(filePath);
|
||||
record.setTime(LocalDateTime.now());
|
||||
competitionVoiceRecordDAO.updateByPrimaryKey(record);
|
||||
@ -539,8 +535,7 @@ public class CompetitionPracticalService implements ICompetitionPracticalService
|
||||
|
||||
private VoiceErrorVO voiceRecordCheck(CompetitionVoiceRecord record, String actionContent, List<String> keyWords) {
|
||||
String filePath = record.getFilePath();
|
||||
String uri = IVoiceService.FileUriPrefix + filePath;
|
||||
byte[] bytes = restTemplate.getForObject(uri, byte[].class);
|
||||
byte[] bytes = VoiceFileUtils.readFile(filePath);
|
||||
VoiceRecognitionResult result = iVoiceTrainingService.voiceRecognition(bytes, filePath);
|
||||
List<String> errorPNCT = new ArrayList<>();
|
||||
String replacedContent = competitionAndScriptManager.pronunciationCheckAndReplace(result.getResult(), actionContent, errorPNCT);
|
||||
|
@ -1,65 +1,14 @@
|
||||
package club.joylink.rtss.services.file;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.AccountVO;
|
||||
import club.joylink.rtss.vo.CommonJsonResponse;
|
||||
import club.joylink.rtss.vo.client.file.FileBindingVO;
|
||||
import club.joylink.rtss.vo.client.file.FileQueryVO;
|
||||
import club.joylink.rtss.vo.client.file.FileVO;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IFileManagerService {
|
||||
|
||||
static String upload(MultipartFile file, String module, String appId, String appSecret, String suffix) {
|
||||
try {
|
||||
//上传文件
|
||||
String url = String.format("https://upload.joylink.club/api/upload/%s?appId=%s&appSecret=%s",
|
||||
module, appId, appSecret);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
|
||||
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
|
||||
ByteArrayResource resource = new ByteArrayResource(file.getBytes()) {
|
||||
@Override
|
||||
public String getFilename() {
|
||||
if (StringUtils.hasText(suffix)) {
|
||||
return file.getOriginalFilename() + ".wav";
|
||||
}
|
||||
return file.getOriginalFilename();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return file.getSize();
|
||||
}
|
||||
};
|
||||
map.add("file", resource);
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
HttpEntity<MultiValueMap<String, Object>> httpEntity =new HttpEntity<>(map, headers);
|
||||
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
|
||||
String body = responseEntity.getBody();
|
||||
// body = body.replaceAll("\\\\", "/");
|
||||
CommonJsonResponse response = JsonUtils.read(body, CommonJsonResponse.class);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(200, response.getCode());
|
||||
return (String) response.getData();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(e);
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
void binding(FileBindingVO fileBindingVO, AccountVO user);
|
||||
|
||||
void updateBasic(FileVO fileVO, AccountVO user);
|
||||
|
@ -1,100 +1,9 @@
|
||||
package club.joylink.rtss.services.voice;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.services.file.IFileManagerService;
|
||||
import club.joylink.rtss.util.JsonUtils;
|
||||
import club.joylink.rtss.vo.CommonJsonResponse;
|
||||
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public interface IVoiceService {
|
||||
String AudioFileBasePath = "/usr/local/joylink/jlcloud/audio/";
|
||||
|
||||
String FileUriPrefix = "https://oss.joylink.club/oss/joylink";
|
||||
AtomicInteger SN = new AtomicInteger(0);
|
||||
static String getFilePath() {
|
||||
LocalDate now = LocalDate.now();
|
||||
String datePath = now.getYear() + File.separator + now.getMonthValue() + File.separator + now.getDayOfMonth();
|
||||
String fileName = System.currentTimeMillis() + "-" + SN.incrementAndGet() + ".wav";
|
||||
String directoryPath = AudioFileBasePath + datePath;
|
||||
File directory = new File(directoryPath);
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs();
|
||||
}
|
||||
String filePath = directoryPath + File.separator + fileName;
|
||||
return filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存语音文件
|
||||
*
|
||||
* @param inputStream 此方法结束时会进行关闭
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
static String saveFile(InputStream inputStream) throws IOException {
|
||||
String localFilePath = getFilePath();
|
||||
OutputStream os = null;
|
||||
File saveFile = null;
|
||||
try {
|
||||
//创建本地文件
|
||||
byte[] bs = new byte[4096];
|
||||
int len;
|
||||
os = new FileOutputStream(localFilePath);
|
||||
while ((len = inputStream.read(bs)) != -1) {
|
||||
os.write(bs, 0, len);
|
||||
}
|
||||
saveFile = new File(localFilePath);
|
||||
//上传文件
|
||||
String url = "https://upload.joylink.club/api/upload/AUDIO?appId=00001&appSecret=joylink00001";
|
||||
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
|
||||
map.add("file", new FileSystemResource(saveFile));
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, map, String.class);
|
||||
String body = responseEntity.getBody();
|
||||
// body = body.replaceAll("\\\\", "/");
|
||||
CommonJsonResponse response = JsonUtils.read(body, CommonJsonResponse.class);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(200, response.getCode());
|
||||
return (String) response.getData();
|
||||
} catch (Exception e) {
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception(e);
|
||||
} finally {
|
||||
if (Objects.nonNull(inputStream)) {
|
||||
inputStream.close();
|
||||
}
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
if (saveFile != null) {
|
||||
saveFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String handleAndSaveFile(MultipartFile file) {
|
||||
String contentType = file.getContentType();
|
||||
BusinessExceptionAssertEnum.UNSUPPORTED_FILE_FORMAT.assertTrue(
|
||||
"audio/wave".equals(contentType) || "audio/wav".equals(contentType) || "audio/x-wav".equals(contentType),
|
||||
String.format("不支持的文件格式[%s]", contentType));
|
||||
try {
|
||||
return IFileManagerService.upload(file, "AUDIO", "00001", "joylink00001", ".wav");
|
||||
} catch (Exception e) {
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 识别服务器收到的语音文件
|
||||
@ -109,18 +18,4 @@ public interface IVoiceService {
|
||||
* @return 文件路径
|
||||
*/
|
||||
String synthesis(String message, String per);
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
class VoiceFile {
|
||||
private String path;
|
||||
|
||||
private File file;
|
||||
|
||||
public VoiceFile(String path, File file) {
|
||||
this.path = path;
|
||||
this.file = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,14 @@ package club.joylink.rtss.services.voice.baidu;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.services.voice.IVoiceService;
|
||||
import club.joylink.rtss.util.VoiceFileUtils;
|
||||
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@Slf4j
|
||||
@Service("baiDuVoiceService")
|
||||
@ -25,7 +24,7 @@ public class BaiduVoiceServiceImpl implements IVoiceService {
|
||||
@Override
|
||||
public VoiceRecognitionResult voiceRecognition(MultipartFile multipartFile, String lang) {
|
||||
try {
|
||||
String filePath = IVoiceService.handleAndSaveFile(multipartFile);
|
||||
String filePath = VoiceFileUtils.saveFile(multipartFile);
|
||||
String json = this.asrService.runJsonPostMethod(multipartFile.getInputStream(), TokenHolder.getInstance().getToken());
|
||||
log.info(String.format("百度语音识别结果:[%s]", json));
|
||||
VoiceAsrResult result = VoiceAsrResult.fromJson(json);
|
||||
@ -44,8 +43,7 @@ public class BaiduVoiceServiceImpl implements IVoiceService {
|
||||
public String synthesis(String message, String per) {
|
||||
try {
|
||||
byte[] data = this.ttsService.run(message, per, TokenHolder.getInstance().getToken());
|
||||
InputStream inputStream = new ByteArrayInputStream(data);
|
||||
return IVoiceService.saveFile(inputStream);//生成的音频数据
|
||||
return VoiceFileUtils.saveFile(data);//生成的音频数据
|
||||
} catch (IOException e) {
|
||||
throw BusinessExceptionAssertEnum.THIRD_SERVICE_CALL_EXCEPTION.exception();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.services.voice.huawei;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.services.voice.IVoiceService;
|
||||
import club.joylink.rtss.util.VoiceFileUtils;
|
||||
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
|
||||
import com.huawei.sis.bean.AuthInfo;
|
||||
import com.huawei.sis.bean.SisConfig;
|
||||
@ -36,8 +37,7 @@ public class HuaweiVoiceServiceImpl implements IVoiceService {
|
||||
|
||||
@Override
|
||||
public VoiceRecognitionResult voiceRecognition(MultipartFile file, String lang) {
|
||||
String filePath = IVoiceService.handleAndSaveFile(file);
|
||||
String data;
|
||||
String filePath = VoiceFileUtils.saveFile(file);
|
||||
try {
|
||||
return voiceRecognition(file.getBytes(), filePath);
|
||||
} catch (IOException e) {
|
||||
|
@ -2,6 +2,7 @@ package club.joylink.rtss.services.voice.xunfei;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.services.voice.IVoiceService;
|
||||
import club.joylink.rtss.util.VoiceFileUtils;
|
||||
import club.joylink.rtss.vo.client.VoiceRecognitionResult;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
@ -15,7 +16,7 @@ public class XunFeiVoiceService implements IVoiceService {
|
||||
|
||||
@Override
|
||||
public VoiceRecognitionResult voiceRecognition(MultipartFile file, String lang) {
|
||||
String filePath = IVoiceService.handleAndSaveFile(file);
|
||||
String filePath = VoiceFileUtils.saveFile(file);
|
||||
try {
|
||||
return voiceRecognition(file.getBytes(), filePath);
|
||||
} catch (IOException e) {
|
||||
@ -43,8 +44,10 @@ public class XunFeiVoiceService implements IVoiceService {
|
||||
webIATWS.buffer = bytes;
|
||||
client.newWebSocket(request, webIATWS);
|
||||
for (int i = 0; i < 20; i++) {
|
||||
if (webIATWS.decoder != null)
|
||||
return new VoiceRecognitionResult(filePath, webIATWS.decoder.toString());
|
||||
if (webIATWS.decoder != null) {
|
||||
String result = webIATWS.decoder.toString();
|
||||
return new VoiceRecognitionResult(filePath, result);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
@ -58,5 +61,4 @@ public class XunFeiVoiceService implements IVoiceService {
|
||||
public String synthesis(String message, String per) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
69
src/main/java/club/joylink/rtss/util/VoiceFileUtils.java
Normal file
69
src/main/java/club/joylink/rtss/util/VoiceFileUtils.java
Normal file
@ -0,0 +1,69 @@
|
||||
package club.joylink.rtss.util;
|
||||
|
||||
import club.joylink.rtss.exception.BusinessExceptionAssertEnum;
|
||||
import club.joylink.rtss.vo.CommonJsonResponse;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class VoiceFileUtils {
|
||||
|
||||
private VoiceFileUtils() {}
|
||||
|
||||
private static final String FileUriPrefix = "https://oss.joylink.club/oss/joylink";
|
||||
|
||||
private static final String UPLOAD_URL = "https://upload.joylink.club/api/upload/AUDIO?appId=%s&appSecret=%s";
|
||||
|
||||
private static final String APP_ID = "00001";
|
||||
|
||||
private static final String APP_SECRET = "joylink00001";
|
||||
|
||||
private static final AtomicInteger SN = new AtomicInteger(0);
|
||||
|
||||
public static String saveFile(byte[] bytes) {
|
||||
try {
|
||||
return upload(bytes);
|
||||
} catch (Exception e) {
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String saveFile(MultipartFile file) {
|
||||
String contentType = file.getContentType();
|
||||
BusinessExceptionAssertEnum.UNSUPPORTED_FILE_FORMAT.assertTrue(
|
||||
"audio/wave".equals(contentType) || "audio/wav".equals(contentType) || "audio/x-wav".equals(contentType),
|
||||
String.format("不支持的文件格式[%s]", contentType));
|
||||
try {
|
||||
return upload(file.getBytes());
|
||||
} catch (Exception e) {
|
||||
throw BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.exception("语音文件上传失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
static String upload(byte[] bytes) {
|
||||
//上传文件
|
||||
String url = String.format(UPLOAD_URL, APP_ID, APP_SECRET);
|
||||
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
|
||||
ByteArrayResource resource = new ByteArrayResource(bytes) {
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return SN.incrementAndGet() + ".wav";
|
||||
}
|
||||
};
|
||||
map.add("file", resource);
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
CommonJsonResponse response = restTemplate.postForObject(url, map, CommonJsonResponse.class);
|
||||
BusinessExceptionAssertEnum.SYSTEM_EXCEPTION.assertEquals(200, response.getCode());
|
||||
return (String) response.getData();
|
||||
}
|
||||
|
||||
public static byte[] readFile(String filePath) {
|
||||
String uri = VoiceFileUtils.FileUriPrefix + filePath;
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
return restTemplate.getForObject(uri, byte[].class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user