From 67f76ab49f5b6c503efcc194bc9125d2c9d4175b Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Sun, 31 Aug 2025 12:43:43 +0800 Subject: [PATCH] 'commit' --- .../Config/__pycache__/Config.cpython-310.pyc | Bin 2310 -> 2310 bytes dsLightRag/Routes/XueBanRoute.py | 12 +- .../__pycache__/XueBanRoute.cpython-310.pyc | Bin 8802 -> 8802 bytes dsLightRag/static/XueBan.html | 289 ------------------ 4 files changed, 5 insertions(+), 296 deletions(-) diff --git a/dsLightRag/Config/__pycache__/Config.cpython-310.pyc b/dsLightRag/Config/__pycache__/Config.cpython-310.pyc index 2c7d682533b14a379d7a334d66470c0f65f370c5..ea70d28371c691701927a32af12f99dee8e1ecdd 100644 GIT binary patch delta 22 ccmZn@Y7^qk=jG*M0D_21n=?2!^8Vxi06AF&-T(jq delta 22 ccmZn@Y7^qk=jG*M00N0~n=`aG^8Vxi05_uryZ`_I diff --git a/dsLightRag/Routes/XueBanRoute.py b/dsLightRag/Routes/XueBanRoute.py index 5604e852..0ef0f98a 100644 --- a/dsLightRag/Routes/XueBanRoute.py +++ b/dsLightRag/Routes/XueBanRoute.py @@ -6,6 +6,11 @@ from datetime import datetime from fastapi import APIRouter, Request, File, UploadFile, WebSocket, WebSocketDisconnect from fastapi.responses import JSONResponse +from Util.XueBanUtil import get_xueban_response_async +from Util.ASRClient import ASRClient +from Util.ObsUtil import ObsUploader +from Util.TTS_Pipeline import stream_and_split_text, StreamingVolcanoTTS + # 创建路由路由器 router = APIRouter(prefix="/api", tags=["学伴"]) @@ -13,13 +18,6 @@ router = APIRouter(prefix="/api", tags=["学伴"]) # 配置日志 logger = logging.getLogger(__name__) -# 导入学伴工具函数、ASR客户端和OBS上传工具 -from Util.XueBanUtil import get_xueban_response_async -from Util.ASRClient import ASRClient -from Util.ObsUtil import ObsUploader -# 导入TTS管道 -from Util.TTS_Pipeline import stream_and_split_text, StreamingVolcanoTTS - # 保留原有的HTTP接口,用于向后兼容 @router.post("/xueban/upload-audio") async def upload_audio(file: UploadFile = File(...)): diff --git a/dsLightRag/Routes/__pycache__/XueBanRoute.cpython-310.pyc b/dsLightRag/Routes/__pycache__/XueBanRoute.cpython-310.pyc index e960f473c097c4e9f772e3f92eae6ee010accee9..b319f121f0485963b327a6d0a52d297b436e3e63 100644 GIT binary patch delta 396 zcmXYrO-lk%6o%)FUo+!;IgXB+iY}sP5p5-kEca0n$lY1@TEdLNWD8dYio1xoe?V8Y zsMTG#4hm`)Eezb{Z)hFOOx**Qhv&SUa~8ElP3b6##CdP@!Opw4O0SPO9I;hLLmF@% zM{V6nphUni+i;R78L(iRP70-*G)eqxkfvd6|Q3pt~1L;8oMt_oT@WNirchLQyoAbZFB)v~RLx(w5g@-u3%U;1ZTg^3j zkm*f+1_o;uW;{rAtJH%Eot7Rqk#^i|+3WR7vfF6;==w8}8rbU5;hxep`bNYk3M(f30$XcjFaQ7m delta 382 zcmXYrJxjw-6ozwdOq;}fHAz2hrE&3N5LXdVX?IZ(KV>?c+bmu&!jr3str|@xu{wLRvX@^t+tyW0!f?zNnRnW zxm-_ojXvNM;fUy)frTyLB9?qRNaOUBWj_;SadyhHelE!4d{Dpz;9RXYN0dIeB2hcw z0nuE^LqsP=SLgsPM*9*;^?{hK9O)LZyHtP`(C8Xm(h_p$0BURtea%3HIY|TQO7!X& z)f=H6L1?gT$pFZ)J^4X`C;DT(!z+8UKfs8MVIgjRPI{ji!Wj#)>j+eOm%o5-wp8#? zlyzMkfz7pI diff --git a/dsLightRag/static/XueBan.html b/dsLightRag/static/XueBan.html index c0021cc6..1c1a0ad7 100644 --- a/dsLightRag/static/XueBan.html +++ b/dsLightRag/static/XueBan.html @@ -109,14 +109,6 @@ -
- - -
@@ -191,286 +183,5 @@
- - // 模型配置 - 使用与Sample.html相同的CDN链接 - const models = { - shizuku: { jsonPath: "https://unpkg.com/live2d-widget-model-shizuku@1.0.5/assets/shizuku.model.json", name: "小智" }, - koharu: { jsonPath: "https://unpkg.com/live2d-widget-model-koharu@1.0.5/assets/koharu.model.json", name: "小荷" }, - wanko: { jsonPath: "https://unpkg.com/live2d-widget-model-wanko@1.0.5/assets/wanko.model.json", name: "汪喵" } - }; - - // 录音相关变量 - 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); - const audioUrl = URL.createObjectURL(audioBlob); - console.log("录音URL:", audioUrl); - // 这里可以调用ASR服务 - 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'; - - // 显示ASR结果 - document.getElementById('asrResultText').textContent = data.asr_text || '未识别到内容'; - - // 显示反馈文本 - document.getElementById('feedbackResultText').textContent = data.feedback_text || '无反馈内容'; - - // 准备音频播放 - if (data.audio_url) { - if (audioElement) { - audioElement.pause(); - audioElement = null; - } - - 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 progressBar = document.getElementById('audioProgress'); - const rect = progressBar.getBoundingClientRect(); - const clickPosition = (e.clientX - rect.left) / rect.width; - audioElement.currentTime = clickPosition * audioElement.duration; - }; - } - } - - // 切换音频播放/暂停 - function togglePlayAudio() { - if (!audioElement) return; - - if (isPlaying) { - audioElement.pause(); - } else { - audioElement.play(); - } - isPlaying = !isPlaying; - updatePlayButton(); - } - - // 更新播放按钮状态 - function updatePlayButton() { - const playButton = document.getElementById('playAudioBtn'); - if (isPlaying) { - playButton.innerHTML = ` - - - - `; - } else { - playButton.innerHTML = ` - - - - `; - } - } - - // 更新音频进度条 - function updateAudioProgress() { - if (!audioElement || !audioElement.duration) return; - - const progress = (audioElement.currentTime / audioElement.duration) * 100; - document.getElementById('progressBar').style.width = `${progress}%`; - } - - // 更新音频时间显示 - function updateAudioTimeDisplay() { - if (!audioElement || !audioElement.duration) return; - - const currentTime = formatTime(audioElement.currentTime); - const duration = formatTime(audioElement.duration); - document.getElementById('audioTime').textContent = `${currentTime} / ${duration}`; - } - - // 格式化时间为 MM:SS - function formatTime(seconds) { - const mins = Math.floor(seconds / 60); - const secs = Math.floor(seconds % 60); - return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; - } - - // 初始化看板娘 - 简化为Sample.html的工作版本 - function initL2Dwidget() { - const modelId = getUrlParam('id') || 'koharu'; - const model = models[modelId] || models.koharu; - - document.getElementById('model-select').value = modelId; - console.log('加载模型:', model.name, model.jsonPath); - - // 初始化模型 - 与Sample.html相同的配置 - L2Dwidget.init({ - "model": { "jsonPath": model.jsonPath, "scale": 1 }, - "display": { - "position": "right", - "width": 150, - "height": 300, - "hOffset": 0, // 重置水平偏移 - "vOffset": -20 // 重置垂直偏移 - }, - "mobile": { "show": true, "scale": 0.5 }, - "react": { "opacityDefault": 0.8, "opacityOnHover": 1 }, - "dialog": { "enable": true, "script": { - 'tap body': `你好啊,我是${model.name}。`, - 'tap face': '有什么问题或者烦心事都可以和我聊聊~' - }} - }); - } - - // 页面加载完成后初始化 - window.onload = function() { - // 直接初始化看板娘,不添加额外延迟 - initL2Dwidget(); - - // 监听下拉框变化(使用独立JS暴露的接口) - document.getElementById('model-select').addEventListener('change', function() { - window.switchL2DModel(this.value); - }); - - // 绑定录音按钮事件 - document.getElementById('startRecordBtn').addEventListener('click', startRecording); - document.getElementById('stopRecordBtn').addEventListener('click', stopRecording); - - // 页面加载时请求麦克风权限 - navigator.mediaDevices.getUserMedia({ audio: true }) - .then(stream => { - console.log("麦克风权限已授予"); - // 立即停止流,只获取权限 - stream.getTracks().forEach(track => track.stop()); - }) - .catch(error => { - console.error("获取麦克风权限失败:", error); - alert("请授权麦克风权限以使用录音功能"); - }); - }; \ No newline at end of file