diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index afe3bee..68e927d 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -199,4 +199,8 @@ chat: praiseUrl: /core/chat/feedback/updateUserFeedback appId: 67cd49095e947ae0ca7fadd8 apiKey: fastgpt-qMl63276wPZvKAxEkW77bur0sSJpmuC6Ngg9lzyEjufLhsBAurjT55j - model: qd-job-turbo \ No newline at end of file + model: qd-job-turbo + +audioText: + asr: http://127.0.0.1:8001/asr/file + tts: http://127.0.0.1:19527/synthesize \ No newline at end of file diff --git a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppSpeechController.java b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppSpeechController.java index 2534b91..d132813 100644 --- a/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppSpeechController.java +++ b/ruoyi-bussiness/src/main/java/com/ruoyi/cms/controller/app/AppSpeechController.java @@ -1,15 +1,22 @@ package com.ruoyi.cms.controller.app; -import com.alibaba.nls.client.AccessToken; -import com.ruoyi.cms.handler.SpeechRecognizerAI; -import com.ruoyi.cms.util.AliyunNlsUtils; +import com.ruoyi.common.annotation.BussinessLog; +import com.ruoyi.common.config.AudioTextRequestClient; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.UnsupportedEncodingException; + +import static com.ruoyi.common.enums.BusinessType.OTHER; /** * app语音Controller @@ -22,11 +29,43 @@ import org.springframework.web.bind.annotation.RestController; @Api(tags = "移动端:用户相关") public class AppSpeechController extends BaseController { - private String appKey = "4lFYn2yPsQymwGu8"; + /*private String appKey = "4lFYn2yPsQymwGu8"; private String id = "LTAI5t9hhSqdDHqwH3RjgyYj"; private String secret = "ni5aW3vxrWouMwcGqJPfh9Uu56PBuv"; - private String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", AliyunNlsUtils.getNlsUrl()+"/ws/v1/"); - @ApiOperation("统计") + private String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", AliyunNlsUtils.getNlsUrl()+"/ws/v1/");*/ + + @Autowired + AudioTextRequestClient audioTextRequestClient; + + @BussinessLog(title = "语音转文字",businessType = OTHER) + @ApiOperation("语音转文字") + @PostMapping(value = "/asr") + public AjaxResult asr(@RequestParam("file") MultipartFile file){ + try { + return AjaxResult.success("请求成功",audioTextRequestClient.getTextFromAudioFile(file)); + }catch (Exception e){ + e.printStackTrace(); + return AjaxResult.error(e.getMessage()); + } + } + + @BussinessLog(title = "文字转语音",businessType = OTHER) + @ApiOperation("文字转语音") + @GetMapping(value = "/tts") + public ResponseEntity tts(@RequestParam("text") String text) throws UnsupportedEncodingException { + byte[] wavData = audioTextRequestClient.getAudioInputStreamFromText(text); + HttpHeaders headers = new HttpHeaders(); + // WAV音频的标准MIME类型 + headers.setContentType(MediaType.parseMediaType("audio/wav")); + // inline:让浏览器在线播放(而非下载) + headers.setContentDispositionFormData("inline", System.currentTimeMillis() + ".wav"); + // 设置内容长度 + headers.setContentLength(wavData.length); + // 4. 返回音频数据 + return new ResponseEntity<>(wavData, headers, HttpStatus.OK); + } + + /*@ApiOperation("统计") @GetMapping("/getToken") public AjaxResult getToken() { @@ -34,5 +73,5 @@ public class AppSpeechController extends BaseController AccessToken accessToken = recognizerDemo.getAccessToken(); String token = AliyunNlsUtils.getNlsUrl()+"/ws/v1/?appkey="+appKey+"&token="+accessToken.getToken(); return AjaxResult.success(token); - } + }*/ } diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index c728f84..68dc5f9 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -158,6 +158,12 @@ lombok + + cn.hutool + hutool-all + 5.7.22 + + \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/AudioTextRequestClient.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/AudioTextRequestClient.java new file mode 100644 index 0000000..17b52e2 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/AudioTextRequestClient.java @@ -0,0 +1,67 @@ +package com.ruoyi.common.config; + +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import com.alibaba.fastjson2.JSONObject; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +@Component +public class AudioTextRequestClient { + + @Value("${audioText.asr}") + private String asr; + + // 1. 读取 TTS 服务地址 + @Value("${audioText.tts}") + private String tts; + + private final RestTemplate restTemplate = new RestTemplate(); + + + public String getTextFromAudioFile(MultipartFile file) throws IOException { + HttpRequest request = HttpRequest.post(asr); + request.header(HttpHeaders.CONTENT_TYPE,MediaType.MULTIPART_FORM_DATA_VALUE); + request.form("file",file.getBytes(),file.getOriginalFilename()); + HttpResponse response = request.execute(); + if(response.isOk()){ + String body = response.body(); + JSONObject jsonObject = JSONObject.parseObject(body); + if("0".equals(jsonObject.getString("code"))){ + return jsonObject.getString("text"); + }else{ + throw new RuntimeException("语音转文字接口调用失败: " + jsonObject.getString("error")); + } + }else{ + throw new RuntimeException("语音转文字接口调用失败: " + response.body()); + } + } + + public byte[] getAudioInputStreamFromText(String audioText) throws UnsupportedEncodingException { + JSONObject object = new JSONObject(); + object.put("text", audioText); + object.put("speaker_id", 0); + object.put("length_scale", 1.0); + object.put("noise_scale", 0.667); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity<>(object.toJSONString(), headers); + ResponseEntity response = restTemplate.postForEntity(tts, entity, byte[].class); + if (!response.getStatusCode().is2xxSuccessful()){ + String body = new String(response.getBody(),"UTF-8"); + JSONObject jsonObject = JSONObject.parseObject(body); + throw new RuntimeException("文字转语音接口调用失败: " + jsonObject.getString("error")); + }else{ + return response.getBody(); + } + } +}