注释阿里云语音服务

This commit is contained in:
sh
2026-04-03 16:56:08 +08:00
parent 73d817bad9
commit 0f09dfbd2c
3 changed files with 292 additions and 292 deletions

View File

@@ -1,77 +1,77 @@
package com.ruoyi.cms.controller.app; //package com.ruoyi.cms.controller.app;
//
import com.ruoyi.common.annotation.BussinessLog; //import com.ruoyi.common.annotation.BussinessLog;
import com.ruoyi.common.config.AudioTextRequestClient; //import com.ruoyi.common.config.AudioTextRequestClient;
import com.ruoyi.common.core.controller.BaseController; //import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; //import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.annotations.Api; //import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; //import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders; //import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; //import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; //import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; //import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; //import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; //import org.springframework.web.multipart.MultipartFile;
//
import java.io.UnsupportedEncodingException; //import java.io.UnsupportedEncodingException;
//
import static com.ruoyi.common.enums.BusinessType.OTHER; //import static com.ruoyi.common.enums.BusinessType.OTHER;
//
/** ///**
* app语音Controller // * app语音Controller
* // *
* @author lishundong // * @author lishundong
* @date 2024-09-03 // * @date 2024-09-03
*/ // */
@RestController //@RestController
@RequestMapping("/app/speech") //@RequestMapping("/app/speech")
@Api(tags = "移动端:用户相关") //@Api(tags = "移动端:用户相关")
public class AppSpeechController extends BaseController //public class AppSpeechController extends BaseController
{ //{
/*private String appKey = "4lFYn2yPsQymwGu8"; // /*private String appKey = "4lFYn2yPsQymwGu8";
private String id = "LTAI5t9hhSqdDHqwH3RjgyYj"; // private String id = "LTAI5t9hhSqdDHqwH3RjgyYj";
private String secret = "ni5aW3vxrWouMwcGqJPfh9Uu56PBuv"; // private String secret = "ni5aW3vxrWouMwcGqJPfh9Uu56PBuv";
private String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", AliyunNlsUtils.getNlsUrl()+"/ws/v1/");*/ // private String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", AliyunNlsUtils.getNlsUrl()+"/ws/v1/");*/
//
@Autowired // @Autowired
AudioTextRequestClient audioTextRequestClient; // AudioTextRequestClient audioTextRequestClient;
//
@BussinessLog(title = "语音转文字",businessType = OTHER) // @BussinessLog(title = "语音转文字",businessType = OTHER)
@ApiOperation("语音转文字") // @ApiOperation("语音转文字")
@PostMapping(value = "/asr") // @PostMapping(value = "/asr")
public AjaxResult asr(@RequestParam("file") MultipartFile file){ // public AjaxResult asr(@RequestParam("file") MultipartFile file){
try { // try {
return AjaxResult.success("请求成功",audioTextRequestClient.getTextFromAudioFile(file)); // return AjaxResult.success("请求成功",audioTextRequestClient.getTextFromAudioFile(file));
}catch (Exception e){ // }catch (Exception e){
e.printStackTrace(); // e.printStackTrace();
return AjaxResult.error(e.getMessage()); // return AjaxResult.error(e.getMessage());
} // }
} // }
//
@BussinessLog(title = "文字转语音",businessType = OTHER) // @BussinessLog(title = "文字转语音",businessType = OTHER)
@ApiOperation("文字转语音") // @ApiOperation("文字转语音")
@GetMapping(value = "/tts") // @GetMapping(value = "/tts")
public ResponseEntity<byte[]> tts(@RequestParam("text") String text) throws UnsupportedEncodingException { // public ResponseEntity<byte[]> tts(@RequestParam("text") String text) throws UnsupportedEncodingException {
byte[] wavData = audioTextRequestClient.getAudioInputStreamFromText(text); // byte[] wavData = audioTextRequestClient.getAudioInputStreamFromText(text);
HttpHeaders headers = new HttpHeaders(); // HttpHeaders headers = new HttpHeaders();
// WAV音频的标准MIME类型 // // WAV音频的标准MIME类型
headers.setContentType(MediaType.parseMediaType("audio/wav")); // headers.setContentType(MediaType.parseMediaType("audio/wav"));
// inline让浏览器在线播放而非下载 // // inline让浏览器在线播放而非下载
headers.setContentDispositionFormData("inline", System.currentTimeMillis() + ".wav"); // headers.setContentDispositionFormData("inline", System.currentTimeMillis() + ".wav");
// 设置内容长度 // // 设置内容长度
headers.setContentLength(wavData.length); // headers.setContentLength(wavData.length);
// 4. 返回音频数据 // // 4. 返回音频数据
return new ResponseEntity<>(wavData, headers, HttpStatus.OK); // return new ResponseEntity<>(wavData, headers, HttpStatus.OK);
} // }
//
/*@ApiOperation("统计") // /*@ApiOperation("统计")
@GetMapping("/getToken") // @GetMapping("/getToken")
public AjaxResult getToken() // public AjaxResult getToken()
{ // {
SpeechRecognizerAI recognizerDemo = new SpeechRecognizerAI(appKey, id, secret, url); // SpeechRecognizerAI recognizerDemo = new SpeechRecognizerAI(appKey, id, secret, url);
AccessToken accessToken = recognizerDemo.getAccessToken(); // AccessToken accessToken = recognizerDemo.getAccessToken();
String token = AliyunNlsUtils.getNlsUrl()+"/ws/v1/?appkey="+appKey+"&token="+accessToken.getToken(); // String token = AliyunNlsUtils.getNlsUrl()+"/ws/v1/?appkey="+appKey+"&token="+accessToken.getToken();
return AjaxResult.success(token); // return AjaxResult.success(token);
}*/ // }*/
} //}

View File

@@ -1,64 +1,64 @@
package com.ruoyi.cms.handler; //package com.ruoyi.cms.handler;
//
import com.ruoyi.cms.util.AliyunNlsUtils; //import com.ruoyi.cms.util.AliyunNlsUtils;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
import javax.websocket.*; //import javax.websocket.*;
import javax.websocket.server.ServerEndpoint; //import javax.websocket.server.ServerEndpoint;
import java.io.ByteArrayInputStream; //import java.io.ByteArrayInputStream;
import java.io.IOException; //import java.io.IOException;
import java.nio.ByteBuffer; //import java.nio.ByteBuffer;
//
@Component //@Component
@ServerEndpoint("/speech-recognition") //@ServerEndpoint("/speech-recognition")
public class SpeechRecognitionWebSocketHandler { //public class SpeechRecognitionWebSocketHandler {
//
private SpeechRecognizerAI recognizerDemo; // private SpeechRecognizerAI recognizerDemo;
//
public SpeechRecognitionWebSocketHandler() { // public SpeechRecognitionWebSocketHandler() {
// 初始化语音识别器 // // 初始化语音识别器
String appKey = "4lFYn2yPsQymwGu8"; // String appKey = "4lFYn2yPsQymwGu8";
String id = "LTAI5t9hhSqdDHqwH3RjgyYj"; // String id = "LTAI5t9hhSqdDHqwH3RjgyYj";
String secret = "ni5aW3vxrWouMwcGqJPfh9Uu56PBuv"; // String secret = "ni5aW3vxrWouMwcGqJPfh9Uu56PBuv";
String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", AliyunNlsUtils.getNlsUrl()+"/ws/v1/"); // String url = System.getenv().getOrDefault("NLS_GATEWAY_URL", AliyunNlsUtils.getNlsUrl()+"/ws/v1/");
recognizerDemo = new SpeechRecognizerAI(appKey, id, secret, url); // recognizerDemo = new SpeechRecognizerAI(appKey, id, secret, url);
} // }
//
/** // /**
* 连接建立成功调用的方法 // * 连接建立成功调用的方法
*/ // */
@OnOpen // @OnOpen
public void onOpen(Session session) { // public void onOpen(Session session) {
System.out.println("WebSocket 连接建立成功sessionId = " + session.getId()); // System.out.println("WebSocket 连接建立成功sessionId = " + session.getId());
} // }
//
/** // /**
* 收到客户端消息后调用的方法 // * 收到客户端消息后调用的方法
*/ // */
@OnMessage(maxMessageSize=5242880) // @OnMessage(maxMessageSize=5242880)
public void onMessage(ByteBuffer message, Session session) throws IOException { // public void onMessage(ByteBuffer message, Session session) throws IOException {
byte[] audioData = new byte[message.remaining()]; // byte[] audioData = new byte[message.remaining()];
message.get(audioData); // message.get(audioData);
//
// 处理音频数据 // // 处理音频数据
recognizerDemo.processStream(session, new ByteArrayInputStream(audioData), 16000); // recognizerDemo.processStream(session, new ByteArrayInputStream(audioData), 16000);
} // }
//
//
/** // /**
* 连接关闭调用的方法 // * 连接关闭调用的方法
*/ // */
@OnClose // @OnClose
public void onClose(Session session) { // public void onClose(Session session) {
System.out.println("WebSocket 连接关闭sessionId = " + session.getId()); // System.out.println("WebSocket 连接关闭sessionId = " + session.getId());
} // }
//
/** // /**
* 发生错误时调用的方法 // * 发生错误时调用的方法
*/ // */
@OnError // @OnError
public void onError(Session session, Throwable error) { // public void onError(Session session, Throwable error) {
System.err.println("WebSocket 发生错误:" + error.getMessage()); // System.err.println("WebSocket 发生错误:" + error.getMessage());
error.printStackTrace(); // error.printStackTrace();
} // }
} //}

View File

@@ -1,151 +1,151 @@
package com.ruoyi.cms.handler; //package com.ruoyi.cms.handler;
//
import com.alibaba.nls.client.AccessToken; //import com.alibaba.nls.client.AccessToken;
import com.alibaba.nls.client.protocol.NlsClient; //import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.OutputFormatEnum; //import com.alibaba.nls.client.protocol.OutputFormatEnum;
import com.alibaba.nls.client.protocol.SampleRateEnum; //import com.alibaba.nls.client.protocol.SampleRateEnum;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer; //import com.alibaba.nls.client.protocol.tts.SpeechSynthesizer;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener; //import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerListener;
import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse; //import com.alibaba.nls.client.protocol.tts.SpeechSynthesizerResponse;
import com.ruoyi.cms.util.AliyunNlsUtils; //import com.ruoyi.cms.util.AliyunNlsUtils;
import org.slf4j.Logger; //import org.slf4j.Logger;
import org.slf4j.LoggerFactory; //import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
import javax.websocket.*; //import javax.websocket.*;
import javax.websocket.server.ServerEndpoint; //import javax.websocket.server.ServerEndpoint;
import java.io.IOException; //import java.io.IOException;
import java.nio.ByteBuffer; //import java.nio.ByteBuffer;
//
@Component //@Component
@ServerEndpoint("/speech-synthesis") //@ServerEndpoint("/speech-synthesis")
public class SpeechSynthesisWebSocketHandler { //public class SpeechSynthesisWebSocketHandler {
private static final Logger logger = LoggerFactory.getLogger(SpeechSynthesisWebSocketHandler.class); // private static final Logger logger = LoggerFactory.getLogger(SpeechSynthesisWebSocketHandler.class);
//
private NlsClient client; // private NlsClient client;
private String appKey = "mtA2pwmvCeefHT3Y"; // private String appKey = "mtA2pwmvCeefHT3Y";
private String accessKeyId = "LTAI5tRBahK93vPNF1JDVEPA"; // private String accessKeyId = "LTAI5tRBahK93vPNF1JDVEPA";
private String accessKeySecret = "x95OWb4cV6ccQVtbEJ2Gxm2Uwl2thJ"; // private String accessKeySecret = "x95OWb4cV6ccQVtbEJ2Gxm2Uwl2thJ";
private String url = AliyunNlsUtils.getNlsUrl()+"/ws/v1/"; // private String url = AliyunNlsUtils.getNlsUrl()+"/ws/v1/";
//
public SpeechSynthesisWebSocketHandler() { // public SpeechSynthesisWebSocketHandler() {
// Initialize NLS client with token // // Initialize NLS client with token
AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret); // AccessToken accessToken = new AccessToken(accessKeyId, accessKeySecret);
try { // try {
if(AliyunNlsUtils.USE_TEST_ENV){ // if(AliyunNlsUtils.USE_TEST_ENV){
accessToken.apply();
}else{
AliyunNlsTokenUtil.generateToken(accessKeyId, accessKeySecret, accessToken);
}
// accessToken.apply(); // accessToken.apply();
String token = accessToken.getToken(); // }else{
if(url.isEmpty()) { // AliyunNlsTokenUtil.generateToken(accessKeyId, accessKeySecret, accessToken);
this.client = new NlsClient(token); // }
} else { // //accessToken.apply();
this.client = new NlsClient(url, token); // String token = accessToken.getToken();
} // if(url.isEmpty()) {
} catch (Exception e) { // this.client = new NlsClient(token);
logger.error("Failed to initialize NLS client", e); // } else {
} // this.client = new NlsClient(url, token);
} // }
// } catch (Exception e) {
@OnOpen // logger.error("Failed to initialize NLS client", e);
public void onOpen(Session session) { // }
logger.info("WebSocket connected for speech synthesis, sessionId: {}", session.getId()); // }
} //
// @OnOpen
@OnMessage(maxMessageSize=5242880) // public void onOpen(Session session) {
public void onMessage(String text, Session session) { // logger.info("WebSocket connected for speech synthesis, sessionId: {}", session.getId());
logger.info("Received text for synthesis: {}", text); // }
//
SpeechSynthesizer synthesizer = null; // @OnMessage(maxMessageSize=5242880)
try { // public void onMessage(String text, Session session) {
// Create synthesizer with a session-specific listener // logger.info("Received text for synthesis: {}", text);
synthesizer = new SpeechSynthesizer(client, createSynthesizerListener(session)); //
// SpeechSynthesizer synthesizer = null;
// Configure synthesizer // try {
synthesizer.setAppKey(appKey); // // Create synthesizer with a session-specific listener
synthesizer.setFormat(OutputFormatEnum.WAV); // synthesizer = new SpeechSynthesizer(client, createSynthesizerListener(session));
synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K); //
synthesizer.setVoice("aiqi"); // // Configure synthesizer
synthesizer.setPitchRate(0); // synthesizer.setAppKey(appKey);
synthesizer.setSpeechRate(0); // synthesizer.setFormat(OutputFormatEnum.WAV);
// synthesizer.setSampleRate(SampleRateEnum.SAMPLE_RATE_16K);
// Use long text synthesis // synthesizer.setVoice("aiqi");
synthesizer.setLongText(text); // synthesizer.setPitchRate(0);
// synthesizer.setSpeechRate(0);
// Start synthesis //
synthesizer.start(); // // Use long text synthesis
// synthesizer.setLongText(text);
} catch (Exception e) { //
logger.error("Error during speech synthesis", e); // // Start synthesis
try { // synthesizer.start();
session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Synthesis error")); //
} catch (IOException ioException) { // } catch (Exception e) {
logger.error("Error closing session", ioException); // logger.error("Error during speech synthesis", e);
} // try {
} finally { // session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "Synthesis error"));
// Note: We can't close the synthesizer here because synthesis is async // } catch (IOException ioException) {
// It should be closed in the listener's onComplete/onFail methods // logger.error("Error closing session", ioException);
} // }
} // } finally {
// // Note: We can't close the synthesizer here because synthesis is async
@OnClose // // It should be closed in the listener's onComplete/onFail methods
public void onClose(Session session) { // }
logger.info("WebSocket closed for speech synthesis, sessionId: {}", session.getId()); // }
} //
// @OnClose
@OnError // public void onClose(Session session) {
public void onError(Session session, Throwable error) { // logger.info("WebSocket closed for speech synthesis, sessionId: {}", session.getId());
logger.error("WebSocket error for session {}: {}", session.getId(), error.getMessage(), error); // }
} //
// @OnError
private SpeechSynthesizerListener createSynthesizerListener(Session session) { // public void onError(Session session, Throwable error) {
return new SpeechSynthesizerListener() { // logger.error("WebSocket error for session {}: {}", session.getId(), error.getMessage(), error);
private boolean firstRecvBinary = true; // }
private long startTime; //
// private SpeechSynthesizerListener createSynthesizerListener(Session session) {
@Override // return new SpeechSynthesizerListener() {
public void onComplete(SpeechSynthesizerResponse response) { // private boolean firstRecvBinary = true;
logger.info("Synthesis completed for session {}, status: {}", session.getId(), response.getStatus()); // private long startTime;
try { //
// Send a close message or marker to indicate completion // @Override
session.getBasicRemote().sendText("{\"status\":\"complete\"}"); // public void onComplete(SpeechSynthesizerResponse response) {
} catch (IOException e) { // logger.info("Synthesis completed for session {}, status: {}", session.getId(), response.getStatus());
logger.error("Error sending completion message", e); // try {
} // // Send a close message or marker to indicate completion
} // session.getBasicRemote().sendText("{\"status\":\"complete\"}");
// } catch (IOException e) {
@Override // logger.error("Error sending completion message", e);
public void onMessage(ByteBuffer message) { // }
try { // }
if (firstRecvBinary) { //
firstRecvBinary = false; // @Override
startTime = System.currentTimeMillis(); // public void onMessage(ByteBuffer message) {
logger.info("First audio packet received for session {}", session.getId()); // try {
} // if (firstRecvBinary) {
// firstRecvBinary = false;
// Send audio data to client // startTime = System.currentTimeMillis();
byte[] bytesArray = new byte[message.remaining()]; // logger.info("First audio packet received for session {}", session.getId());
message.get(bytesArray, 0, bytesArray.length); // }
session.getBasicRemote().sendBinary(ByteBuffer.wrap(bytesArray)); //
// // Send audio data to client
} catch (IOException e) { // byte[] bytesArray = new byte[message.remaining()];
logger.error("Error sending audio data to client", e); // message.get(bytesArray, 0, bytesArray.length);
} // session.getBasicRemote().sendBinary(ByteBuffer.wrap(bytesArray));
} //
// } catch (IOException e) {
@Override // logger.error("Error sending audio data to client", e);
public void onFail(SpeechSynthesizerResponse response) { // }
logger.error("Synthesis failed for session {}: task_id: {}, status: {}, status_text: {}", // }
session.getId(), response.getTaskId(), response.getStatus(), response.getStatusText()); //
try { // @Override
session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, // public void onFail(SpeechSynthesizerResponse response) {
"Synthesis failed: " + response.getStatusText())); // logger.error("Synthesis failed for session {}: task_id: {}, status: {}, status_text: {}",
} catch (IOException e) { // session.getId(), response.getTaskId(), response.getStatus(), response.getStatusText());
logger.error("Error closing failed session", e); // try {
} // session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION,
} // "Synthesis failed: " + response.getStatusText()));
}; // } catch (IOException e) {
} // logger.error("Error closing failed session", e);
} // }
// }
// };
// }
//}