dataV-xunfei/index.js

247 lines
6.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// (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()
}