vue3对接科大讯飞实时语音转写

1,020 阅读2分钟

官方demo包下载

  1. 官网地址

js demo

微信图片_20240815201514.png

vue3 demo

- js包引入

image.png

封装公共组件

1.官方获取 APPID API_KEY

image.png 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>