Files
dsProject/dsLightRag/static/YunXiao/xueban.js
2025-08-28 15:35:54 +08:00

153 lines
5.7 KiB
JavaScript

// 学伴录音功能核心逻辑
// 模型配置
// 录音相关变量
let mediaRecorder; let audioChunks = []; let isRecording = false;
// 音频播放相关变量
let audioElement = null; let isPlaying = false;
// 获取URL参数
function getUrlParam(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
const r = window.location.search.substr(1).match(reg);
return r ? unescape(r[2]) : null;
}
// 开始录音
function startRecording() {
if (isRecording) return;
console.log("尝试开始录音");
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
mediaRecorder = new MediaRecorder(stream);
audioChunks = [];
mediaRecorder.ondataavailable = event => {
if (event.data.size > 0) audioChunks.push(event.data);
};
mediaRecorder.onstop = () => {
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
console.log("录音完成,音频数据大小:", audioBlob.size);
uploadAudioToServer(audioBlob);
};
mediaRecorder.start();
isRecording = true;
document.getElementById('recordingIndicator').style.display = 'flex';
document.getElementById('startRecordBtn').style.display = 'none';
document.getElementById('stopRecordBtn').style.display = 'flex';
console.log("开始录音成功");
// 设置最长录音时间为60秒
setTimeout(stopRecording, 60000);
})
.catch(error => {
console.error("获取麦克风权限失败:", error);
alert("请授权麦克风权限以使用录音功能");
});
}
// 停止录音
function stopRecording() {
if (!isRecording || !mediaRecorder) return;
mediaRecorder.stop();
isRecording = false;
document.getElementById('recordingIndicator').style.display = 'none';
document.getElementById('startRecordBtn').style.display = 'flex';
document.getElementById('stopRecordBtn').style.display = 'none';
console.log("停止录音");
if (mediaRecorder.stream) {
mediaRecorder.stream.getTracks().forEach(track => track.stop());
}
}
// 上传音频到服务器
function uploadAudioToServer(audioBlob) {
console.log("开始上传音频到服务器");
document.getElementById('thinkingIndicator').style.display = 'flex';
const formData = new FormData();
formData.append('file', audioBlob, 'recording.wav');
fetch('/api/xueban/upload-audio', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) throw new Error('服务器响应错误');
return response.json();
})
.then(data => {
console.log("处理结果:", data);
document.getElementById('thinkingIndicator').style.display = 'none';
if (data.success) {
showResults(data.data);
} else {
alert('音频处理失败: ' + data.message);
}
})
.catch(error => {
console.error("上传音频失败:", error);
document.getElementById('thinkingIndicator').style.display = 'none';
alert('上传音频失败: ' + error.message);
});
}
// 显示ASR识别结果和反馈
function showResults(data) {
const resultContainer = document.getElementById('resultContainer');
resultContainer.style.display = 'flex';
document.getElementById('asrResultText').textContent = data.asr_text || '未识别到内容';
document.getElementById('feedbackResultText').textContent = data.feedback_text || '无反馈内容';
if (data.audio_url) {
if (audioElement) audioElement.pause();
audioElement = new Audio(data.audio_url);
audioElement.onloadedmetadata = function() {
updateAudioTimeDisplay();
try { audioElement.play(); isPlaying = true; updatePlayButton(); }
catch (e) { console.error("自动播放失败:", e); }
};
audioElement.ontimeupdate = function() { updateAudioProgress(); updateAudioTimeDisplay(); };
audioElement.onended = function() { isPlaying = false; updatePlayButton(); };
document.getElementById('playAudioBtn').onclick = togglePlayAudio;
document.getElementById('audioProgress').onclick = function(e) {
const rect = this.getBoundingClientRect();
audioElement.currentTime = (e.clientX - rect.left) / rect.width * audioElement.duration;
};
}
}
// 音频播放控制函数
function togglePlayAudio() {
if (!audioElement) return;
isPlaying ? audioElement.pause() : audioElement.play();
isPlaying = !isPlaying;
updatePlayButton();
}
function updatePlayButton() {
const btn = document.getElementById('playAudioBtn');
btn.innerHTML = isPlaying ?
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M6 19H10V5H6V19ZM14 19H18V5H14V19Z" fill="white"/></svg>' :
'<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M8 5V19L19 12L8 5Z" fill="white"/></svg>';
}
function updateAudioProgress() {
if (!audioElement) return;
const progress = (audioElement.currentTime / audioElement.duration) * 100;
document.getElementById('progressBar').style.width = `${progress}%`;
}
function updateAudioTimeDisplay() {
if (!audioElement) return;
const format = s => `${Math.floor(s/60).toString().padStart(2,'0')}:${Math.floor(s%60).toString().padStart(2,'0')}`;
document.getElementById('audioTime').textContent = `${format(audioElement.currentTime)} / ${format(audioElement.duration)}`;
}