'commit'
This commit is contained in:
@@ -1153,6 +1153,143 @@ select { padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; backgrou
|
||||
</div>
|
||||
<script src="https://l2dwidget.js.org/lib/L2Dwidget.min.js"></script>
|
||||
<script>
|
||||
// 录音相关变量
|
||||
let mediaRecorder; let audioChunks = []; let isRecording = false;
|
||||
// 音频播放相关变量
|
||||
let audioElement = null; let isPlaying = false;
|
||||
|
||||
// 开始录音
|
||||
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); }
|
||||
document.getElementById('playAudioBtn').style.display = 'flex';
|
||||
};
|
||||
audioElement.ontimeupdate = function() { updateAudioProgress(); updateAudioTimeDisplay(); };
|
||||
audioElement.onended = function() { isPlaying = false; updatePlayButton(); };
|
||||
document.getElementById('playAudioBtn').onclick = togglePlayAudio;
|
||||
document.getElementById('audioProgress').onclick = function(e) {
|
||||
if (!audioElement) return;
|
||||
const rect = this.getBoundingClientRect();
|
||||
const clickPosition = (e.clientX - rect.left) / rect.width;
|
||||
audioElement.currentTime = clickPosition * 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" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 19H10V5H6V19ZM14 19H18V5H14V19Z" fill="white"/>
|
||||
</svg>` : `
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 5V19L19 12L8 5Z" fill="white"/>
|
||||
</svg>`;
|
||||
}
|
||||
function updateAudioProgress() { if (audioElement) document.getElementById('progressBar').style.width = `${(audioElement.currentTime/audioElement.duration)*100}%`; }
|
||||
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)}`;
|
||||
}
|
||||
|
||||
// 模型配置映射
|
||||
const modelConfig = {
|
||||
shizuku: {
|
||||
@@ -1264,5 +1401,8 @@ select { padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; backgrou
|
||||
// 初始加载默认模型
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initL2DWidget();
|
||||
// 添加录音按钮事件绑定
|
||||
document.getElementById('startRecordBtn').addEventListener('click', startRecording);
|
||||
document.getElementById('stopRecordBtn').addEventListener('click', stopRecording);
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user