官方demo包下载
js demo
vue3 demo
- js包引入
封装公共组件
1.官方获取 APPID API_KEY
2.代码封装
<!-- 实时语音转文字交互 -->
<template>
<div>
<div class="textarea-bottom">
<span @click="startLuyin" :style="btnTxt == '录音中' ? 'color:#F54A45' : ''">
{{ btnTxt }}
</span>
</div>
</div>
</template>
<script setup>
import { ref,onMounted } from 'vue'
const btnStatus = ref("UNDEFINED")//当前状态
const btnTxt = ref("开始录音")//当前状态-text
const type = ref()//当前状态步骤
var recorder, iatWS
onMounted(() => {
recorder = new RecorderManager("/recorder");
recorder.onStart = () => {
changeBtnStatus("OPEN");
};
recorder.onFrameRecorded = ({ isLastFrame, frameBuffer }) => {
console.log('传递的数据', frameBuffer);
if (iatWS.readyState === iatWS.OPEN) {
iatWS.send(new Int8Array(frameBuffer));
if (isLastFrame) {
iatWS.send('{"end": true}');
changeBtnStatus("CLOSING");
}
}
};
recorder.onStop = () => {
// clearInterval(this.countdownInterval);
};
})
// 开始录音
const startLuyin = () => {
if (btnStatus.value === "UNDEFINED" || btnStatus.value === "CLOSED") {
connectWebSocket();
} else if (btnStatus.value === "CONNECTING" || btnStatus.value === "OPEN") {
// 结束录音
recorder.stop();
}
}
// 创建ws实时通讯
const 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,
});
};
iatWS.onmessage = (e) => {
renderResult(e.data);
};
iatWS.onerror = (e) => {
console.error("连接出错", e);
recorder.stop();
changeBtnStatus("CLOSED");
};
iatWS.onclose = (e) => {
type.value = 3;
console.log("断开连接", e);
recorder.stop();
changeBtnStatus("CLOSED");
};
}
// 前端获取ws地址
const APPID = "****";
const API_KEY = "********";
const getWebSocketUrl = () => {
var url = "wss://rtasr.xfyun.cn/v1/ws";
var appId = APPID;
var secretKey = API_KEY;
var ts = Math.floor(new Date().getTime() / 1000);
var signa = hex_md5(appId + ts);
var signatureSha = CryptoJSNew.HmacSHA1(signa, secretKey);
var signature = CryptoJS.enc.Base64.stringify(signatureSha);
signature = encodeURIComponent(signature);
return `${url}?appid=${appId}&ts=${ts}&signa=${signature}`;
}
// 切换状态
const changeBtnStatus=(status)=>{
btnStatus.value = status;
if (status === "CONNECTING") {
btnTxt.value = "建立连接中";
resultText.value = "";
} else if (status === "OPEN") {
btnTxt.value = "录音中";
} else if (status === "CLOSING") {
btnTxt.value = "关闭连接中";
} else if (status === "CLOSED") {
btnTxt.value = "开始录音";
}
}
// 处理获取的数据
const resultText = ref('');//获取的最终文字数据
const renderResult=(resultData)=> {
let jsonData = JSON.parse(resultData);
if (jsonData.action == "started") {
type.value = 1;
// console.log("握手成功");
} else if (jsonData.action == "result") {
type.value = 2;
const data = JSON.parse(jsonData.data);
// 转写结果
let resultTextTemp = "";
data.cn.st.rt.forEach((j) => {
j.ws.forEach((k) => {
k.cw.forEach((l) => {
if (l.rl != 0) {
resultTextTemp += resultText.value ? "\n" : "";
}
resultTextTemp += l.w;
});
});
});
if (data.cn.st.type == 0) {
// 【最终】识别结果:
resultText.value += resultTextTemp;
console.log("我想要的结果是个啥", resultText.value);
// this.$emit("realtime", resultText.value);
resultTextTemp = "";
}
} else if (jsonData.action == "error") {
// 连接发生错误
console.log("出错了:", jsonData);
}
}
</script>
<style>
.input-cl {
width: 100%;
height: calc(100vh - 545px);
}
.textarea-bottom {
background: #fff;
height: 30px;
width: 100%;
border-radius: 0 0 6px 6px !important;
border-top: 1px solid #ebeef5;
display: flex;
justify-content: center;
align-items: center;
padding-right: 10px;
>span {
cursor: pointer;
}
}
</style>