package com.newyetai.sdk.xf.service; import cn.hutool.json.JSON; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.xfyun.api.RtasrClient; import cn.xfyun.model.response.rtasr.RtasrResponse; import cn.xfyun.service.rta.AbstractRtasrWebSocketListener; import com.newyetai.common.AlitaResult; import com.newyetai.common.util.JsonUtils; import com.newyetai.sdk.xf.config.XfProperties; import java.io.InputStream; import java.util.concurrent.CountDownLatch; import okhttp3.Response; import okhttp3.WebSocket; import org.apache.commons.codec.binary.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * ( Real-time ASR ) 实时语音转写 1、APPID、APIKey信息获取:... 2、文档地址:... * * @author kaili23 */ public class RtasrClientApp extends AbstractRtasrWebSocketListener{ private static final Logger logger = LoggerFactory.getLogger(RtasrClientApp.class); /** * 记录完整结果 */ private StringBuffer finalResult = new StringBuffer(); private AlitaResult result; /** * 线程同步 */ private CountDownLatch latch; RtasrClientApp(CountDownLatch latch){ this.latch = latch; } public AlitaResult getResult() { return result; } @Override public void onSuccess(WebSocket webSocket, String text) { RtasrResponse response = JsonUtils.toObject(text, RtasrResponse.class); // finalResult为服务端已转写的完整语句,后面拼接服务端本次返回的当前语句的转写中间结果。 String tempResult = handleAndReturnContent(response.getData()); logger.info("实时转写结果:{}", finalResult + tempResult); result = AlitaResult.success(finalResult.toString()); } @Override public void onFail(WebSocket webSocket, Throwable t, Response response) { result = AlitaResult.bizError(t.getMessage()); latch.countDown(); } @Override public void onBusinessFail(WebSocket webSocket, String text) { logger.error("业务异常,返回信息为:{}", text); result = AlitaResult.bizError(text); latch.countDown(); } @Override public void onClosing(WebSocket webSocket, int code, String reason) { latch.countDown(); } @Override public void onClosed() { latch.countDown(); } public static AlitaResult execute(InputStream is, String from, XfProperties xfProperties) { try { CountDownLatch latch = new CountDownLatch(1); RtasrClientApp app = new RtasrClientApp(latch); RtasrClient client = new RtasrClient.Builder() .signature(xfProperties.getAppId(), xfProperties.getRtasr().getApiKey()) .lang(from) // 设置此参数需需开通翻译功能,请在控制台申请并开通 // .targetLang(to) .build(); client.send(is, app); latch.await(); return app.getResult(); } catch (Exception e) { if (e instanceof InterruptedException) { Thread.currentThread().interrupt(); } logger.error("语音转写失败", e); return AlitaResult.error("语音转写失败:{}", e.getMessage()); } } /** * 解析转写流式响应,更新实时结果,返回此次的中间结果 */ public String handleAndReturnContent(String message) { StringBuilder tempResult = new StringBuilder(); try { // 解析本次服务端返回的文本内容 JSONObject messageObj = JSONUtil.parseObj(message); JSONObject cn = messageObj.getJSONObject("cn"); JSONObject st = cn.getJSONObject("st"); JSONArray rtArr = st.getJSONArray("rt"); for (int i = 0; i < rtArr.size(); i++) { JSONObject rtArrObj = rtArr.getJSONObject(i); JSONArray wsArr = rtArrObj.getJSONArray("ws"); for (int j = 0; j < wsArr.size(); j++) { JSONObject wsArrObj = wsArr.getJSONObject(j); JSONArray cwArr = wsArrObj.getJSONArray("cw"); for (int k = 0; k < cwArr.size(); k++) { JSONObject cwArrObj = cwArr.getJSONObject(k); String wStr = cwArrObj.getStr("w"); tempResult.append(wStr); } } } // 根据中间结果类型更新最终结果 String type = st.getStr("type"); if (StringUtils.equals("1", type)) { // 此时服务端返回的是当前语句的实时转写内容,不保存到最终结果中,返回到调用处进行拼接展示。 return tempResult.toString(); } else if (StringUtils.equals("0", type)) { // 此时服务端返回的是当前语句的完整转写内容,保存到最终结果中,并返回空字符串。 finalResult.append(tempResult); return ""; } else { logger.warn("未知的转写响应类型:{}", type); return tempResult.toString(); } } catch (Exception e) { return message; } } }