155 lines
5.0 KiB
Java
155 lines
5.0 KiB
Java
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信息获取:<a
|
||
* href="https://console.xfyun.cn/services/rta">...</a> 2、文档地址:<a
|
||
* href="https://www.xfyun.cn/doc/asr/rtasr/API.html">...</a>
|
||
*
|
||
* @author kaili23
|
||
*/
|
||
public class RtasrClientApp extends AbstractRtasrWebSocketListener{
|
||
|
||
private static final Logger logger = LoggerFactory.getLogger(RtasrClientApp.class);
|
||
|
||
/**
|
||
* 记录完整结果
|
||
*/
|
||
private StringBuffer finalResult = new StringBuffer();
|
||
|
||
private AlitaResult<String> result;
|
||
|
||
/**
|
||
* 线程同步
|
||
*/
|
||
private CountDownLatch latch;
|
||
|
||
RtasrClientApp(CountDownLatch latch){
|
||
this.latch = latch;
|
||
}
|
||
|
||
public AlitaResult<String> 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();
|
||
webSocket.close(1000, "");
|
||
}
|
||
|
||
@Override
|
||
public void onBusinessFail(WebSocket webSocket, String text) {
|
||
logger.error("业务异常,返回信息为:{}", text);
|
||
result = AlitaResult.bizError(text);
|
||
latch.countDown();
|
||
webSocket.close(1000, "");
|
||
}
|
||
|
||
@Override
|
||
public void onClosing(WebSocket webSocket, int code, String reason) {
|
||
latch.countDown();
|
||
webSocket.close(1000, "");
|
||
}
|
||
|
||
@Override
|
||
public void onClosed() {
|
||
latch.countDown();
|
||
}
|
||
|
||
public static AlitaResult<String> 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;
|
||
}
|
||
}
|
||
|
||
}
|