const chatIcon = document.getElementById('chatIcon'); const chatDialog = document.getElementById('chatDialog'); const closeChat = document.getElementById('closeChat'); const voiceInputBtn = document.getElementById('voiceInputBtn'); const voiceStatus = document.getElementById('voiceStatus'); const notificationBadge = document.querySelector('.notification-badge'); var APPID = "43341b7e"; var API_SECRET = "MWQzMWEyYTAyYzVlZWRjOTM1NjE0MjI4"; var API_KEY = "a46e1fc5d062a14b28cde0ff2c0046e1"; let btnStatus = "UNDEFINED"; // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED" //大模型调用部分 const apiPassword = "xozAvYSDDAUrZtmZAMHe:BesWfhINSVtAumsVcxCt"; // 注意:请将 123456 替换为你自己的 APIPassword let chatList = [ { "role": "system", "content": "请你扮演一名幼师,跟我聊聊天吧!" } ] async function sendRequest(str,callback) { chatList.push({ "role": "user", "content": str }) const body = { "apiPassword": apiPassword, "chatList": chatList } let data= await fetch('http://w.textbox.wang/index.php/english/Index/xhchat', { method: 'POST', // 或者使用 'GET' 取决于API的要求 headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(body) }) .then(response => response.json()) // 解析JSON响应 .then(data => { // 处理响应数据 console.log(data.choices[0].message.content); chatList.push({ "role": "assistant", "content": data.choices[0].message.content }) callback(data.choices[0].message.content) // document.getElementById('output').innerText = data.text; // 假设响应中包含文本字段 }) .catch(error => console.error('Error:', error)); // 捕获并处理错误 } // 执行请求 //语音播报部分 let preText = ""; function speakFly(text) { if (preText == text) { return } preText = text; const audioPlayer = document.getElementById('chatAudio'); const vcn = ["x4_lingxiaoqi_cts", "x4_lingyouyou", "x4_lingfeizhe_zl", "aisjinger", "aisbabyxu"]; $.ajax({ url: 'http://rgclass.iflysse.com:8200/text2audio', type: 'POST', contentType: 'application/x-www-form-urlencoded', data: { text: text, vcn: vcn[1], speed: 50 }, headers: { 'Cache-Control': 'no-store' }, success: function (data) { let timer01 = setTimeout(function () { $(".message-content:last").text(text) $(".chat-content").animate({ scrollTop: $(".chat-content")[0].scrollHeight }, 1000); const url = `http://rgclass.iflysse.com:8200${data}`; audioPlayer.src = url; audioPlayer.load(); audioPlayer.play(); audioPlayer.onerror = function (e) { setTimeout(function () { audioPlayer.load(); audioPlayer.play(); }, 500); console.error(e); }; audioPlayer.addEventListener('ended', () => {//连续对话 voiceInputBtn.click(); }); clearTimeout(timer01); // console.log("text2audio success", url, audioPlayer); }, 1000); }, error: function (jqXHR, textStatus, errorThrown) { console.error('text2audio error:', textStatus, errorThrown); } }); let timer02 = setTimeout(function () { preText = ""; clearTimeout(timer02); }, 5000); } const recorder = new RecorderManager("./dist"); recorder.onStart = () => { changeBtnStatus("OPEN"); } let iatWS; let resultText = ""; let resultTextTemp = ""; let countdownInterval; let isListening = false; /** * 获取websocket url * 该接口需要后端提供,这里为了方便前端处理 */ function getWebSocketUrl() { // 请求地址根据语种不同变化 var url = "wss://iat-api.xfyun.cn/v2/iat"; var host = "iat-api.xfyun.cn"; var apiKey = API_KEY; var apiSecret = API_SECRET; var date = new Date().toGMTString(); var algorithm = "hmac-sha256"; var headers = "host date request-line"; var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`; var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret); var signature = CryptoJS.enc.Base64.stringify(signatureSha); var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`; var authorization = btoa(authorizationOrigin); url = `${url}?authorization=${authorization}&date=${date}&host=${host}`; return url; } function toBase64(buffer) { var binary = ""; var bytes = new Uint8Array(buffer); var len = bytes.byteLength; for (var i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return window.btoa(binary); } function changeBtnStatus(status) { btnStatus = status; if (status === "CONNECTING") { // btnControl.innerText = "建立连接中"; // document.getElementById("partial-result").innerText = ""; resultText = ""; resultTextTemp = ""; } } let lydjs=null; function renderResult(resultData) { clearTimeout(lydjs); lydjs=setTimeout(function(){ iatWS.close(); },3000); // 识别结束 let jsonData = JSON.parse(resultData); if (jsonData.data && jsonData.data.result) { let data = jsonData.data.result; let str = ""; let ws = data.ws; for (let i = 0; i < ws.length; i++) { str = str + ws[i].cw[0].w; } console.log(str); // 开启wpgs会有此字段(前提:在控制台开通动态修正功能) // 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段 if (data.pgs) { if (data.pgs === "apd") { // 将resultTextTemp同步给resultText resultText = resultTextTemp; // 移除打字指示器 } // 将结果存储在resultTextTemp中 resultTextTemp = resultText + str; } else { resultText = resultText + str; } $(".typing-indicator").text(resultTextTemp); // document.getElementById("partial-result").innerText = // resultTextTemp || resultText || ""; } 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"); console.log(iatWS); iatWS.onopen = (e) => { isListening = true; voiceInputBtn.classList.add('active'); voiceInputBtn.innerHTML = ''; voiceStatus.textContent = '正在聆听...'; // 添加用户正在说话的UI反馈 addMessage('user', '