xiaochan 4 bulan lalu
induk
melakukan
903feaeaf2

+ 15 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/tts/Tts.java

@@ -0,0 +1,15 @@
+package org.thyy.thirdpartapi.tts;
+
+import jakarta.servlet.http.HttpServletResponse;
+import org.thyy.utils.result.ResultVo;
+
+
+public interface Tts {
+
+    ResultVo<String> textToSpeech(TtsRequest request, HttpServletResponse response);
+
+    default void init(TtsConfig config, TtsConfig.Config currentConfig) {
+
+    }
+
+}

+ 25 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/tts/TtsConfig.java

@@ -0,0 +1,25 @@
+package org.thyy.thirdpartapi.tts;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+@Component
+@Data
+@ConfigurationProperties("thyy.tts")
+public class TtsConfig {
+
+    @Data
+    public static class Config {
+        private String appId;
+        private String apiKey;
+        private String apiSecret;
+    }
+
+    private Map<String, Config> config;
+    private String directory;
+    private String speechUrl;
+
+}

+ 55 - 0
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/tts/TtsController.java

@@ -0,0 +1,55 @@
+package org.thyy.thirdpartapi.tts;
+
+import jakarta.annotation.PostConstruct;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.thyy.utils.result.ResultVo;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/xfTtsApi")
+@Slf4j
+public class TtsController {
+
+    private final Map<String, Tts> ttsServices;
+    private final TtsConfig ttsConfig;
+    private Tts ttsService;
+
+    public TtsController(Map<String, Tts> ttsServices, TtsConfig ttsConfig) {
+        this.ttsServices = ttsServices;
+        this.ttsConfig = ttsConfig;
+    }
+
+    @PostConstruct
+    public void init() {
+        for (Map.Entry<String, Tts> map : ttsServices.entrySet()) {
+            String key = map.getKey();
+            if (ttsConfig.getConfig() == null) {
+                return;
+            }
+            TtsConfig.Config config = ttsConfig.getConfig().get(key);
+            if (config != null) {
+                try {
+                    map.getValue().init(ttsConfig, config);
+                    ttsService = map.getValue();
+
+                } catch (Exception e) {
+                    log.error("语言合成错误", e);
+                }
+                return;
+            }
+        }
+    }
+
+
+    @PostMapping("/textToSpeech")
+    public ResultVo<String> textToSpeech(@RequestBody TtsRequest request, HttpServletResponse response) {
+        return ttsService.textToSpeech(request, response);
+    }
+
+}

+ 1 - 1
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/xfyun/request/TtsRequest.java → thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/tts/TtsRequest.java

@@ -1,4 +1,4 @@
-package org.thyy.thirdpartapi.xfyun.request;
+package org.thyy.thirdpartapi.tts;
 
 import lombok.Data;
 

+ 37 - 42
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/xfyun/XfTtsApi.java → thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/tts/ttsService/XfTtsApi.java

@@ -1,47 +1,41 @@
-package org.thyy.thirdpartapi.xfyun;
+package org.thyy.thirdpartapi.tts.ttsService;
 
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.xfyun.api.TtsClient;
 import cn.xfyun.model.response.TtsResponse;
 import cn.xfyun.service.tts.AbstractTtsWebSocketListener;
-import jakarta.annotation.PostConstruct;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
 import okhttp3.Response;
 import okhttp3.WebSocket;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import org.thyy.thirdpartapi.xfyun.request.TtsRequest;
+import org.springframework.stereotype.Service;
+import org.thyy.thirdpartapi.tts.Tts;
+import org.thyy.thirdpartapi.tts.TtsConfig;
+import org.thyy.thirdpartapi.tts.TtsRequest;
 import org.thyy.utils.exception.ExceptionEnum;
 import org.thyy.utils.result.R;
 import org.thyy.utils.result.ResultVo;
 
 import java.io.File;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicReference;
 
 @Slf4j
-@RestController
-@RequestMapping("/xfTts")
-public class XfTtsApi {
+@Service(value = "xf")
+public class XfTtsApi implements Tts {
     private TtsClient ttsClient;
-    private final XfConfig cfg;
+    private TtsConfig cfg;
 
-    @Autowired
-    public XfTtsApi(XfConfig cfg) {
-        this.cfg = cfg;
-    }
-
-    @PostConstruct
-    public void initTtsClient() {
+    public void init(TtsConfig cfg, TtsConfig.Config xf) {
         try {
+            this.cfg = cfg;
             if (StrUtil.isBlank(cfg.getDirectory())) {
                 cfg.setDirectory(System.getProperty("user.dir"));
             }
             ttsClient = new TtsClient.Builder()
-                    .signature(cfg.getAppId(), cfg.getApiKey(), cfg.getApiSecret())
+                    .signature(xf.getAppId(), xf.getApiKey(), xf.getApiSecret())
                     .vcn("aisjinger").volume(100).build();
             log.info("讯飞SDK初始化成功。");
         } catch (Exception e) {
@@ -49,30 +43,28 @@ public class XfTtsApi {
         }
     }
 
-    @PostMapping("/textToSpeech")
-    public ResultVo<String> textToSpeech(@RequestBody TtsRequest request) {
+
+    public ResultVo<String> textToSpeech(TtsRequest request, HttpServletResponse response) {
         String filePath = cfg.getDirectory() + File.separator + request.getId() + ".mp3";
         FileUtil.del(filePath);
 
-        final Boolean[] progress = { false, null };
-        final String[] message = {""};
-        try  {
+        CompletableFuture<Void> future = new CompletableFuture<>();
+
+        try {
             File file = new File(filePath);
             ttsClient.send(request.getText(), new AbstractTtsWebSocketListener(file) {
                 @Override
                 public void onSuccess(byte[] bytes) {
-                    progress[0] = true;
                 }
+
                 @Override
                 public void onFail(WebSocket webSocket, Throwable throwable, Response response) {
                     log.error("[onFail]生成语音文件失败:{}", throwable.getMessage());
-                    message[0] = throwable.getMessage();
                 }
 
                 @Override
                 public void onBusinessFail(WebSocket webSocket, TtsResponse ttsResponse) {
                     log.error("[onBusinessFail]生成语音文件失败:{}", ttsResponse.toString());
-                    message[0] = ttsResponse.toString();
                 }
 
                 @Override
@@ -83,29 +75,32 @@ public class XfTtsApi {
                 @Override
                 public void onClosed(WebSocket webSocket, int code, String reason) {
                     super.onClosed(webSocket, code, reason);
-                    progress[1] = true;
+                    future.complete(null);
                 }
             });
         } catch (Exception e) {
             log.error("生成语音文件失败", e);
             log.error("错误码查询链接:https://www.xfyun.cn/document/error-code");
-            message[0] = e.getMessage();
-            progress[1] = true;
+            future.completeExceptionally(e);
         }
 
-        while (null == progress[1]) {
-            try {
-                TimeUnit.MILLISECONDS.sleep(1000);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
+        String voiceUrl = cfg.getSpeechUrl() + "/" + request.getId() + ".mp3";
+        AtomicReference<ResultVo<String>> resultVo = new AtomicReference<>(R.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, ""));
+
+        future.whenComplete((result, ex) -> {
+            if (ex != null) {
+                resultVo.set(R.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, ex.getMessage()));
+            } else {
+                resultVo.set(R.ok(voiceUrl));
             }
-        }
-        if (StrUtil.isNotBlank(message[0])) {
-            return R.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, message[0]);
+        });
+        try {
+            future.get();
+        } catch (InterruptedException | ExecutionException e) {
+            return R.fail(ExceptionEnum.INTERNAL_SERVER_ERROR, e.getMessage());
         }
 
-        String voiceUrl = cfg.getSpeechUrl() + "/" + request.getId() + ".mp3";
-        return R.ok(voiceUrl);
+        return resultVo.get();
     }
 
 }

+ 0 - 16
thyy-thirdpart-api/src/main/java/org/thyy/thirdpartapi/xfyun/XfConfig.java

@@ -1,16 +0,0 @@
-package org.thyy.thirdpartapi.xfyun;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-@Data
-@Component
-@ConfigurationProperties(prefix = "thyy.xfyun")
-public class XfConfig {
-    private String appId;
-    private String apiKey;
-    private String apiSecret;
-    private String directory;
-    private String speechUrl;
-}

+ 7 - 7
thyy-thirdpart-api/src/main/resources/application.yml

@@ -3,13 +3,13 @@ spring:
     name: thyy-thirdpart-api
 server:
   port: 21701
-  servlet:
-    context-path: /thyy/thirdpart/api
 
 thyy:
-  xfyun:
-    app-id: fdde4cef
-    api-key: 95a78dd3cfcc4863e3c003352ca8ec65
-    api-secret: OWZjZGE4NjI3MDdkYzg4ZjllY2VjNGQ0
+  tts:
     directory: D:\a.snapshot\resource\voice
-    speechUrl: http://172.16.32.160:8080/resource/voice
+    speech-url: http://172.16.32.160:8080/resource/voice
+    config:
+      xf:
+        app-id: fdde4cef
+        api-key: 95a78dd3cfcc4863e3c003352ca8ec65
+        api-secret: OWZjZGE4NjI3MDdkYzg4ZjllY2VjNGQ0