2023-10-11 20:39:47 +08:00
|
|
|
|
// (function () {
|
|
|
|
|
|
|
|
|
|
// // btnControl.onclick = function () {
|
|
|
|
|
// // if (btnStatus === "UNDEFINED" || btnStatus === "CLOSED") {
|
|
|
|
|
// // connectWebSocket();
|
|
|
|
|
// // } else if (btnStatus === "CONNECTING" || btnStatus === "OPEN") {
|
|
|
|
|
// // // 结束录音
|
|
|
|
|
// // recorder.stop();
|
|
|
|
|
// // }
|
|
|
|
|
// // };
|
|
|
|
|
// })();
|
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
let btnStatus = 'UNDEFINED' // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED"
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
// const btnControl = document.getElementById("btn_control");
|
|
|
|
|
const btnControl = {}
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
const recorder = new RecorderManager('./dists')
|
|
|
|
|
recorder.onStart = () => {
|
|
|
|
|
changeBtnStatus('OPEN')
|
|
|
|
|
}
|
|
|
|
|
let iatWS
|
|
|
|
|
let resultText = ''
|
|
|
|
|
let resultTextTemp = ''
|
|
|
|
|
let countdownInterval
|
|
|
|
|
window.winText = ''
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
/**
|
2023-10-11 20:39:47 +08:00
|
|
|
|
* 获取websocket url
|
|
|
|
|
* 该接口需要后端提供,这里为了方便前端处理
|
|
|
|
|
*/
|
2023-10-12 15:48:10 +08:00
|
|
|
|
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
|
|
|
|
|
}
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
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])
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
return window.btoa(binary)
|
|
|
|
|
}
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
function countdown() {
|
|
|
|
|
let seconds = 60
|
|
|
|
|
btnControl.innerText = `录音中(${seconds}s)`
|
|
|
|
|
countdownInterval = setInterval(() => {
|
|
|
|
|
seconds = seconds - 1
|
|
|
|
|
if (seconds <= 0) {
|
|
|
|
|
clearInterval(countdownInterval)
|
|
|
|
|
recorder.stop()
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
btnControl.innerText = `录音中(${seconds}s)`
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
}, 1000)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function changeBtnStatus(status) {
|
|
|
|
|
btnStatus = status
|
|
|
|
|
if (status === 'CONNECTING') {
|
|
|
|
|
btnControl.innerText = '建立连接中'
|
2023-10-13 09:46:54 +08:00
|
|
|
|
// document.getElementById('result').innerText = ''
|
2023-10-12 15:48:10 +08:00
|
|
|
|
resultText = ''
|
|
|
|
|
resultTextTemp = ''
|
|
|
|
|
}
|
|
|
|
|
else if (status === 'OPEN') {
|
|
|
|
|
countdown()
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
else if (status === 'CLOSING') {
|
|
|
|
|
btnControl.innerText = '关闭连接中'
|
|
|
|
|
}
|
|
|
|
|
else if (status === 'CLOSED') {
|
|
|
|
|
btnControl.innerText = '开始录音'
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
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
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
// 将结果存储在resultTextTemp中
|
|
|
|
|
resultTextTemp = resultText + str
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
else {
|
|
|
|
|
resultText = resultText + str
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-13 09:46:54 +08:00
|
|
|
|
// document.getElementById('result').innerText
|
|
|
|
|
// = resultTextTemp || resultText || ''
|
2023-10-12 15:48:10 +08:00
|
|
|
|
console.log('录音结果:', resultTextTemp || resultText || '')
|
|
|
|
|
window.winText = resultTextTemp || resultText || ''
|
|
|
|
|
window.dispatchEvent(new Event('test'))
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
if (jsonData.code === 0 && jsonData.data.status === 2)
|
|
|
|
|
iatWS.close()
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
if (jsonData.code !== 0) {
|
|
|
|
|
iatWS.close()
|
|
|
|
|
console.error(jsonData)
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
}
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
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',
|
|
|
|
|
},
|
2023-10-11 20:39:47 +08:00
|
|
|
|
}
|
2023-10-12 15:48:10 +08:00
|
|
|
|
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')
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-11 20:39:47 +08:00
|
|
|
|
|
2023-10-12 15:48:10 +08:00
|
|
|
|
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')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
recorder.onStop = () => {
|
|
|
|
|
clearInterval(countdownInterval)
|
|
|
|
|
}
|
|
|
|
|
function RecordXunfei() {
|
|
|
|
|
if (btnStatus === 'UNDEFINED' || btnStatus === 'CLOSED') {
|
|
|
|
|
console.log('开始录音')
|
|
|
|
|
connectWebSocket()
|
|
|
|
|
}
|
|
|
|
|
else if (btnStatus === 'CONNECTING' || btnStatus === 'OPEN') {
|
|
|
|
|
console.log('结束录音')
|
|
|
|
|
// 结束录音
|
|
|
|
|
recorder.stop()
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-15 15:37:04 +08:00
|
|
|
|
|
|
|
|
|
// 重新录制
|
|
|
|
|
function reRecordXunfei() {
|
|
|
|
|
if (btnStatus === 'CONNECTING' || btnStatus === 'OPEN') {
|
|
|
|
|
console.log('重新录制')
|
|
|
|
|
connectWebSocket()
|
|
|
|
|
}
|
|
|
|
|
}
|