let mediaRecorder; let audioChunks = []; let audioBlob; // 获取DOM元素 const languageSelect = document.getElementById('language'); const textInput = document.getElementById('text'); const recordBtn = document.getElementById('recordBtn'); const stopBtn = document.getElementById('stopBtn'); const statusDiv = document.getElementById('status'); const resultDiv = document.getElementById('result'); const resultContent = document.getElementById('resultContent'); // 语言切换时自动填充示例文本 // 移除语言切换事件监听 // languageSelect.addEventListener('change', () => { // if (languageSelect.value === 'chinese') { // textInput.value = '窗前明月光,疑是地上霜。'; // } else { // textInput.value = 'Nice to meet you.'; // } // }); // 移除页面加载事件监听 // window.addEventListener('load', () => { // textInput.value = '窗前明月光,疑是地上霜。'; // stopBtn.disabled = true; // }); // 开始录音 recordBtn.addEventListener('click', async () => { try { statusDiv.textContent = '正在获取麦克风权限...'; statusDiv.className = 'status'; // 获取麦克风权限并处理可能的错误 const stream = await navigator.mediaDevices.getUserMedia({ audio: true }) .catch(err => { if (err.name === 'NotAllowedError') { throw new Error('用户拒绝了麦克风访问权限。请在浏览器设置中允许麦克风访问,或刷新页面重试。'); } else if (err.name === 'NotFoundError') { throw new Error('未检测到麦克风设备,请确保您的设备已正确连接麦克风。'); } else if (err.name === 'NotReadableError') { throw new Error('麦克风设备正在被其他程序占用,请关闭其他可能使用麦克风的程序后重试。'); } else { throw err; } }); // 检测浏览器支持的录制格式 const getSupportedMimeType = () => { const options = [ 'audio/webm; codecs=opus', 'audio/webm', 'audio/mp4', '' // 空字符串表示使用浏览器默认格式 ]; for (const option of options) { if (MediaRecorder.isTypeSupported(option)) return option; } return ''; }; // 使用检测到的格式初始化 mediaRecorder = new MediaRecorder(stream, { mimeType: getSupportedMimeType(), audioBitsPerSecond: 16000 }); // 同时修正Blob类型(确保前后一致) mediaRecorder.onstop = () => { audioBlob = new Blob(audioChunks, { type: 'audio/webm' }); // 与录制格式匹配 statusDiv.textContent = '录音完成,正在自动提交评测...'; submitEvaluation(); // 停止所有音轨以释放麦克风 stream.getTracks().forEach(track => track.stop()); }; // 设置60秒自动停止录音 const maxRecordingTime = 60000; // 60秒 const timeoutId = setTimeout(() => { if (mediaRecorder && mediaRecorder.state === 'recording') { alert('已达到最大录音时长(60秒)'); mediaRecorder.stop(); recordBtn.disabled = false; stopBtn.disabled = true; } }, maxRecordingTime); mediaRecorder.start(); statusDiv.textContent = '正在录音...(最多60秒)'; recordBtn.disabled = true; stopBtn.disabled = false; } catch (error) { console.error('录音初始化失败:', error); alert('录音失败: ' + error.message); statusDiv.textContent = '录音失败: ' + error.message; statusDiv.className = 'status error'; recordBtn.disabled = false; stopBtn.disabled = true; } }); // 停止录音 stopBtn.addEventListener('click', () => { if (mediaRecorder && mediaRecorder.state === 'recording') { mediaRecorder.stop(); recordBtn.disabled = false; stopBtn.disabled = true; } }); // 提交评测 async function submitEvaluation() { if (!audioBlob) { statusDiv.textContent = '请先完成录音'; statusDiv.className = 'status error'; return; } // 移除文本验证 // if (!textInput.value.trim()) { // statusDiv.textContent = '请输入评测文本内容'; // statusDiv.className = 'status error'; // return; // } try { statusDiv.textContent = '正在提交评测...'; statusDiv.className = 'status'; const formData = new FormData(); formData.append('audio_file', audioBlob, 'recording.webm'); formData.append('language', languageSelect.value); // 移除文本参数 // formData.append('text', textInput.value.trim()); formData.append('group', 'adult'); formData.append('check_type', 'common'); formData.append('grade', 'middle'); const response = await fetch('/api/xunFei/evaluate-audio', { method: 'POST', body: formData }); if (!response.ok) { throw new Error(`服务器错误: HTTP状态码 ${response.status}`); } const result = await response.json(); if (result.status === 'success') { displayResults(result.results); statusDiv.textContent = '评测成功完成'; statusDiv.className = 'status success'; } else { throw new Error(result.error_message || '评测失败,服务器返回未知错误'); } } catch (error) { console.error('评测提交失败:', error); statusDiv.textContent = '评测失败: ' + error.message; statusDiv.className = 'status error'; } } // 显示评测结果 function displayResults(results) { resultDiv.style.display = 'block'; if (!results) { resultContent.innerHTML = '
暂无评测结果
'; return; } let html = '总分: ${results.total_score.toFixed(4)} / 5.0
`; } // 显示各项评分 if (results.accuracy_score !== undefined) { html += `准确度: ${results.accuracy_score.toFixed(4)}
`; } // 添加结果对象有效性检查 if (!results) { showError("评测结果格式错误"); return; } if (results.fluency_score !== undefined) { html += `流利度: ${results.fluency_score.toFixed(4)}
`; } else { html += `流利度: 未获取
`; // 添加默认值 } if (results.completeness_score !== undefined) { html += `完整度: ${results.completeness_score.toFixed(4)}
`; } else { html += `完整度: 未获取
`; // 添加默认值 } html += '