// (function () { // // btnControl.onclick = function () { // // if (btnStatus === "UNDEFINED" || btnStatus === "CLOSED") { // // connectWebSocket(); // // } else if (btnStatus === "CONNECTING" || btnStatus === "OPEN") { // // // 结束录音 // // recorder.stop(); // // } // // }; // })(); let btnStatus = 'UNDEFINED' // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED" // const btnControl = document.getElementById("btn_control"); const btnControl = {} const recorder = new RecorderManager('./dists') recorder.onStart = () => { changeBtnStatus('OPEN') } let iatWS let resultText = '' let resultTextTemp = '' let countdownInterval window.winText = '' /** * 获取websocket url * 该接口需要后端提供,这里为了方便前端处理 */ function getWebSocketUrl() { // 请求地址根据语种不同变化 let url = 'wss://iat-api.xfyun.cn/v2/iat' const host = 'iat-api.xfyun.cn' const apiKey = API_KEY const apiSecret = API_SECRET const date = new Date().toGMTString() const algorithm = 'hmac-sha256' const headers = 'host date request-line' const signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1` const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret) const signature = CryptoJS.enc.Base64.stringify(signatureSha) const authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"` const authorization = btoa(authorizationOrigin) url = `${url}?authorization=${authorization}&date=${date}&host=${host}` return url } function toBase64(buffer) { let binary = '' const bytes = new Uint8Array(buffer) const len = bytes.byteLength for (let i = 0; i < len; i++) binary += String.fromCharCode(bytes[i]) return window.btoa(binary) } function countdown() { if (countdownInterval) clearInterval(countdownInterval) let seconds = 60 btnControl.innerText = `录音中(${seconds}s)` countdownInterval = setInterval(() => { seconds = seconds - 1 if (seconds <= 0) { clearInterval(countdownInterval) recorder.stop() } else { btnControl.innerText = `录音中(${seconds}s)` } }, 1000) } function changeBtnStatus(status) { btnStatus = status if (status === 'CONNECTING') { btnControl.innerText = '建立连接中' // document.getElementById('result').innerText = '' resultText = '' resultTextTemp = '' } else if (status === 'OPEN') { // countdown() } else if (status === 'CLOSING') { btnControl.innerText = '关闭连接中' } else if (status === 'CLOSED') { btnControl.innerText = '开始录音' } } function renderResult(resultData) { // 识别结束 const jsonData = JSON.parse(resultData) if (jsonData.data && jsonData.data.result) { const data = jsonData.data.result let str = '' const 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 } // document.getElementById('result').innerText // = resultTextTemp || resultText || '' console.log('录音结果:', resultTextTemp || resultText || '') window.winText = resultTextTemp || resultText || '' window.dispatchEvent(new Event('test')) } 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, }) const params = { common: { app_id: APPID, }, business: { language: 'zh_cn', domain: 'iat', accent: 'mandarin', vad_eos: 5000, 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) => { console.log('录音关闭', e) recorder.stop() changeBtnStatus('CLOSED') } } recorder.onFrameRecorded = ({ isLastFrame, frameBuffer }) => { if (iatWS.readyState === iatWS.OPEN) { iatWS.send( JSON.stringify({ data: { // status: isLastFrame ? 2 : 1, status: 1, format: 'audio/L16;rate=16000', encoding: 'raw', audio: toBase64(frameBuffer), }, }), ) if (isLastFrame) changeBtnStatus('CLOSING') } } recorder.onStop = () => { clearInterval(countdownInterval) } function RecordXunfei() { if (btnStatus === 'UNDEFINED' || btnStatus === 'CLOSED') { console.log('准备开始录音') connectWebSocket() } else if (btnStatus === 'CONNECTING' || btnStatus === 'OPEN') { console.log('准备结束录音') iatWS.close() // 结束录音 recorder.stop() } } function getRecordStatus() { return btnStatus } function getIAT() { return iatWS } // 重新录制 function reRecordXunfei() { if (iatWS && iatWS.readyState !== WebSocket.CLOSED) { iatWS.onclose = () => { console.log('重新录制') connectWebSocket() } iatWS.close() } else { console.log('重新录制') connectWebSocket() } } function stopRecord() { iatWS.close() recorder.stop() }