You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.7 KiB
168 lines
4.7 KiB
import {setScrollPosition} from "./util.js"
|
|
|
|
const APPID = "5c2055f8";
|
|
const API_SECRET = "2bc7168506a38cf1a7a52fb3ba63d873";
|
|
const API_KEY = "2d1e9e5604d66089bda42ff4797201c1";
|
|
|
|
let btnStatus = "UNDEFINED"; // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED"
|
|
|
|
const recorder = new window.RecorderManager("/iflyrec");
|
|
recorder.onStart = () => {
|
|
changeBtnStatus("OPEN");
|
|
}
|
|
let iatWS;
|
|
let resultText = "";
|
|
let resultTextTemp = "";
|
|
|
|
/**
|
|
* 获取websocket url
|
|
* 该接口需要后端提供,这里为了方便前端处理
|
|
*/
|
|
function getWebSocketUrl() {
|
|
// 请求地址根据语种不同变化
|
|
var url = "wss://iat-api.xfyun.cn/v2/iat";
|
|
var host = "iat-api.xfyun.cn";
|
|
var apiKey = API_KEY;
|
|
var apiSecret = API_SECRET;
|
|
var date = new Date().toGMTString();
|
|
var algorithm = "hmac-sha256";
|
|
var headers = "host date request-line";
|
|
var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`;
|
|
var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
|
|
var signature = CryptoJS.enc.Base64.stringify(signatureSha);
|
|
var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
|
|
var authorization = btoa(authorizationOrigin);
|
|
url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
|
|
return url;
|
|
}
|
|
|
|
function toBase64(buffer) {
|
|
var binary = "";
|
|
var bytes = new Uint8Array(buffer);
|
|
var len = bytes.byteLength;
|
|
for (var i = 0; i < len; i++) {
|
|
binary += String.fromCharCode(bytes[i]);
|
|
}
|
|
return window.btoa(binary);
|
|
}
|
|
function changeBtnStatus(status) {
|
|
btnStatus = status;
|
|
console.log(status);
|
|
if (status === "CONNECTING") {
|
|
resultText = "";
|
|
resultTextTemp = "";
|
|
} else if (status === "CLOSED") {
|
|
console.log("结束语音");
|
|
audioStop();
|
|
}
|
|
}
|
|
|
|
function islinstren(msg){
|
|
if(window.cli){
|
|
window.cli.innerText = msg;
|
|
}
|
|
setScrollPosition();
|
|
}
|
|
|
|
function renderResult(resultData) {
|
|
// 识别结束
|
|
let jsonData = JSON.parse(resultData);
|
|
if (jsonData.data && jsonData.data.result) {
|
|
let data = jsonData.data.result;
|
|
let str = "";
|
|
let ws = data.ws;
|
|
for (let i = 0; i < ws.length; i++) {
|
|
str = str + ws[i].cw[0].w;
|
|
}
|
|
// 开启wpgs会有此字段(前提:在控制台开通动态修正功能)
|
|
// 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段
|
|
if (data.pgs) {
|
|
if (data.pgs === "apd") {
|
|
// 将resultTextTemp同步给resultText
|
|
resultText = resultTextTemp;
|
|
}
|
|
// 将结果存储在resultTextTemp中
|
|
resultTextTemp = resultText + str;
|
|
} else {
|
|
resultText = resultText + str;
|
|
}
|
|
islinstren(resultTextTemp || resultText || "");
|
|
}
|
|
if (jsonData.code === 0 && jsonData.data.status === 2) {
|
|
iatWS.close();
|
|
}
|
|
if (jsonData.code !== 0) {
|
|
iatWS.close();
|
|
console.error(jsonData);
|
|
}
|
|
}
|
|
|
|
function connectWebSocket() {
|
|
const websocketUrl = getWebSocketUrl();
|
|
if ("WebSocket" in window) {
|
|
iatWS = new WebSocket(websocketUrl);
|
|
} else if ("MozWebSocket" in window) {
|
|
iatWS = new MozWebSocket(websocketUrl);
|
|
} else {
|
|
alert("浏览器不支持WebSocket");
|
|
return;
|
|
}
|
|
changeBtnStatus("CONNECTING");
|
|
iatWS.onopen = (e) => {
|
|
// 开始录音
|
|
recorder.start({
|
|
sampleRate: 16000,
|
|
frameSize: 1280,
|
|
});
|
|
var params = {
|
|
common: {
|
|
app_id: APPID,
|
|
},
|
|
business: {
|
|
language: "zh_cn",
|
|
domain: "iat",
|
|
accent: "mandarin",
|
|
vad_eos: 2000,
|
|
dwa: "wpgs",
|
|
},
|
|
data: {
|
|
status: 0,
|
|
format: "audio/L16;rate=16000",
|
|
encoding: "raw",
|
|
},
|
|
};
|
|
iatWS.send(JSON.stringify(params));
|
|
};
|
|
iatWS.onmessage = (e) => {
|
|
renderResult(e.data);
|
|
};
|
|
iatWS.onerror = (e) => {
|
|
console.error(e);
|
|
recorder.stop();
|
|
changeBtnStatus("CLOSED");
|
|
};
|
|
iatWS.onclose = (e) => {
|
|
recorder.stop();
|
|
changeBtnStatus("CLOSED");
|
|
};
|
|
}
|
|
|
|
recorder.onFrameRecorded = ({ isLastFrame, frameBuffer }) => {
|
|
if (iatWS.readyState === iatWS.OPEN) {
|
|
iatWS.send(
|
|
JSON.stringify({
|
|
data: {
|
|
status: isLastFrame ? 2 : 1,
|
|
format: "audio/L16;rate=16000",
|
|
encoding: "raw",
|
|
audio: toBase64(frameBuffer),
|
|
},
|
|
})
|
|
);
|
|
if (isLastFrame) {
|
|
changeBtnStatus("CLOSING");
|
|
}
|
|
}
|
|
};
|
|
|
|
export {btnStatus,recorder,getWebSocketUrl,connectWebSocket}
|