packagecom.example.combat.asrutils;importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONObject;importcom.example.combat.config.constant.ContentTypeEnum;importcom.example.combat.config.constant.HttpMethodEnum;importcom.example.combat.config.constant.SignMenodEnum;import com.example.combat.asrutils.param.*;importcom.example.combat.afsutils.HttpUtil;importcom.example.combat.afsutils.SignUtils;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.stereotype.Component;importorg.springframework.util.StringUtils;import java.util.*;/*** @description: 语音识别工具类
*@author: zhucj
* @date: 2019-11-23 15:30*/@Component
@Slf4jpublic classASRUtil {
@Value("${tencent.secretId}")privateString sercretId;
@Value("${tencent.secretKey}")privateString sercretKey;/*** 一句话识别
*@paramparam
*@return
*/
publicR sentenceRecognition(SentenceRecognition param){//获取公共请求参数
TreeMap treeMap = createPublicMap("SentenceRecognition", "2019-06-14");
HashMap hashMap = new HashMap<>();
hashMap.put("ProjectId",0);
hashMap.put("SubServiceType",2);
hashMap.put("EngSerViceType","8k");
hashMap.put("SourceType",param.getSourceType());
verifyVoiceFormat(param.getVoiceFormat());
hashMap.put("VoiceFormat",param.getVoiceFormat());
hashMap.put("UsrAudioKey",IDUtil.createIdbyUUID());if (Objects.equals(0,param.getSourceType())){if(StringUtils.isEmpty(param.getUrl())){throw new ASRRuntimeException(SystemConstants.PARAM_INCORRECT_CODE,"传入语音Url类型时,传入的url不能为空");
}//如果是语音Url,只需要传Url
hashMap.put("Url",param.getUrl());
}else if (Objects.equals(1,param.getSourceType())){if (StringUtils.isEmpty(param.getData()) ||StringUtils.isEmpty(param.getDataLen()) ){throw new ASRRuntimeException(SystemConstants.PARAM_INCORRECT_CODE,"传入语音数据类型时,传入的语音数据和长度不能为空");
}if(param.getDataLen()>614400){ throw new ASRRuntimeException(SystemConstants.PARAM_INCORRECT_CODE,"传入的音频文件不能超过600kb");}
hashMap.put("Data",param.getData());
hashMap.put("DataLen",param.getDataLen());
}else{throw new ASRRuntimeException(SystemConstants.PARAM_INCORRECT_CODE,"语音数据来源,传入的类型错误");
}//签名,公共参数不需要放到body中
String sign = null;try{
sign=SignUtils.sign(treeMap, HttpMethodEnum.POST, SignMenodEnum.TC3_HMAC_SHA256, JSON.toJSONString(hashMap)
, SentenceRecognitionApi.SENTENCE_RECOGNITION, sercretKey, ContentTypeEnum.JSON);
}catch(Exception e) {
log.error("签名异常:{}",e.getMessage());return R.error("签名异常").setCode(SystemConstants.SERVER_ERROR_CODE);
}try{
String respJson= HttpUtil.httpPost(SentenceRecognitionApi.SENTENCE_RECOGNITION, JSON.parseObject(sign,Map.class),hashMap);
JSONObject jsonObject=JSON.parseObject(respJson);
String response= jsonObject.getString("Response");
JSONObject error=(JSONObject) JSON.parseObject(response).get("Error");if(Objects.nonNull(error)){return R.error(String.valueOf(error.get("Message"))).setCode(SystemConstants.SERVER_ERROR_CODE);
}else{
SentenceResponse sentenceResponse= JSON.parseObject(response, SentenceResponse.class);returnR.ok(sentenceResponse.getResult()).setCode(SystemConstants.SUCCESS_CODE);
}
}catch(Exception e) {
log.error("语音识别失败:{}",e.getMessage());return R.error("语音识别失败").setCode(SystemConstants.SERVER_ERROR_CODE);
}
}/*** 录音文件识别
*@paramcreateRecTask
*@return
*/
publicR createRecTask(CreateRecTask createRecTask){
TreeMap treeMap= createPublicMap("CreateRecTask", "2019-06-14");
HashMap hashMap = newHashMap();
hashMap.put("EngineModelType","8k_0");
hashMap.put("ChannelNum",1);
hashMap.put("ResTextFormat",0);
hashMap.put("SourceType",createRecTask.getSourceType());if (Objects.equals(createRecTask.getSourceType(),0)){
hashMap.put("Url",createRecTask.getUrl());
}else if (Objects.equals(createRecTask.getSourceType(),1)){
hashMap.put("Data",createRecTask.getData());if (createRecTask.getDataLen()>5*1024*1024){throw new ASRRuntimeException(SystemConstants.PARAM_INCORRECT_CODE,"录音文件不能超过5MB");
}
hashMap.put("DataLen",createRecTask.getDataLen());
}//签名,公共参数不需要放到body中
String sign = null;try{
sign=SignUtils.sign(treeMap, HttpMethodEnum.POST, SignMenodEnum.TC3_HMAC_SHA256, JSON.toJSONString(hashMap)
, SentenceRecognitionApi.SENTENCE_RECOGNITION, sercretKey, ContentTypeEnum.JSON);
}catch(Exception e) {
log.error("签名异常:{}",e.getMessage());return R.error("签名异常").setCode(SystemConstants.SERVER_ERROR_CODE);
}try{
String respJson= HttpUtil.httpPost(SentenceRecognitionApi.SENTENCE_RECOGNITION, JSON.parseObject(sign,Map.class),hashMap);
JSONObject jsonObject=JSON.parseObject(respJson);
String response= jsonObject.getString("Response");
JSONObject error=(JSONObject) JSON.parseObject(response).get("Error");if(Objects.nonNull(error)){return R.error(String.valueOf(error.get("Message"))).setCode(SystemConstants.SERVER_ERROR_CODE);
}else{
JSONObject data=(JSONObject) JSON.parseObject(response).get("Data");
String taskId=String.valueOf(data.get("TaskId"));//通过TaskId查询识别内容
returndescribeTaskStatus(taskId);
}
}catch(Exception e) {
log.error("语音识别失败:{}",e.getMessage());return R.error("语音识别失败").setCode(SystemConstants.SERVER_ERROR_CODE);
}
}/*** 通过任务ID查询识别结果
*@paramtaskId
*@return
*/
publicR describeTaskStatus(String taskId){
TreeMap treeMap= createPublicMap("DescribeTaskStatus", "2019-06-14");
HashMap hashMap = new HashMap<>();
hashMap.put("TaskId",Integer.valueOf(taskId));//签名,公共参数不需要放到body中
String sign = null;try{
sign=SignUtils.sign(treeMap, HttpMethodEnum.POST, SignMenodEnum.TC3_HMAC_SHA256, JSON.toJSONString(hashMap)
, SentenceRecognitionApi.SENTENCE_RECOGNITION, sercretKey, ContentTypeEnum.JSON);
}catch(Exception e) {
log.error("签名异常:{}",e.getMessage());return R.error("签名异常").setCode(SystemConstants.SERVER_ERROR_CODE);
}try{
String respJson= HttpUtil.httpPost(SentenceRecognitionApi.SENTENCE_RECOGNITION, JSON.parseObject(sign,Map.class),hashMap);
JSONObject jsonObject=JSON.parseObject(respJson);
String response= jsonObject.getString("Response");
CreateRecTaskResponse createRecTaskResponse= JSON.parseObject(response, CreateRecTaskResponse.class);
Data data=createRecTaskResponse.getData();if (Objects.equals(data.getStatus(),0)){returndescribeTaskStatus(taskId);
}else if (Objects.equals(data.getStatus(),1)){returndescribeTaskStatus(taskId);
}else if (Objects.equals(data.getStatus(),2)){returnR.ok(data.getResult()).setCode(SystemConstants.SUCCESS_CODE);
}else{returnR.error(data.getErrorMsg()).setCode(SystemConstants.SERVER_ERROR_CODE);
}
}catch(Exception e) {
log.error("任务ID查询识别失败:{}",e.getMessage());return R.error("任务ID查询识别失败").setCode(SystemConstants.SERVER_ERROR_CODE);
}
}/*** 封装请求公共参数
*@paramaction
*@paramversion
*@return
*/
publicTreeMap createPublicMap(String action, String version){
TreeMap treeMap = new TreeMap<>();
treeMap.put("Action",action);
treeMap.put("Version",version);
treeMap.put("Timestamp",getCurrentTimestamp());
treeMap.put("Nonce",newRandom().nextInt(Integer.MAX_VALUE));
treeMap.put("SecretId",sercretId);returntreeMap;
}/*** 获取当前时间戳,单位秒
*@return
*/
public static longgetCurrentTimestamp() {return System.currentTimeMillis()/1000;
}public voidverifyVoiceFormat(String type){if (Objects.equals("mp3",type) || Objects.equals("wav",type)){return;
}else{throw new ASRRuntimeException(SystemConstants.PARAM_INCORRECT_CODE,"传入识别音频的音频格式错误");
}
}
}