From 04e84055587f0753e7499711de00c903022bcfe1 Mon Sep 17 00:00:00 2001 From: hubian <908234780@qq.com> Date: Tue, 21 Apr 2026 18:35:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=89=8D=E7=AB=AF=E5=BD=95=E9=9F=B3?= =?UTF-8?q?=E6=94=B9=E7=94=A8WAV=E6=A0=BC=E5=BC=8F=EF=BC=88PCM=2016kHz?= =?UTF-8?q?=EF=BC=89=EF=BC=8C=E5=85=BC=E5=AE=B9=E6=A8=A1=E5=9E=8B=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/server.cpython-310.pyc | Bin 0 -> 4473 bytes cert.pem | 29 +++++++++ key.pem | 52 +++++++++++++++ logs/server.log | Bin 0 -> 3015 bytes main.py | 9 ++- server.py | 11 +--- static/index.html | 100 +++++++++++++++++++++++------ 7 files changed, 173 insertions(+), 28 deletions(-) create mode 100644 __pycache__/server.cpython-310.pyc create mode 100644 cert.pem create mode 100644 key.pem create mode 100644 logs/server.log diff --git a/__pycache__/server.cpython-310.pyc b/__pycache__/server.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f0f53b4b025ed0f689c1e9fbb333c5e29b9f669f GIT binary patch literal 4473 zcmbtXZ)_CD72loR+ui%)!x$SIW8fg*a5VS=N!x_dl*B+o8w|xxP_C6$%gxwcv$uPl z-Q)1}9GODWDA6UMjViSX$z4OFp#Gs%(^N^6MpeI5{nXFFDCMdVltmBrt&Evqd6VLbUrQG zy0fm>neUV(CO6hogT|XA-^DhFUVpINilm zwquhtuF^qz@1+>%y9d6olkSEu>|#4WDogiVQh~pV_0cb!CH#-VvV-|SHaK-J>!5ep8s{`TNUQ+-}`8p+FoYG2}WP7j|rHG15p z)L|8iGvLG@vwU{kqs$4{A3t&U$P?!1kyB3{8$Mz_dFqMk#>pTk9mwSzuV6Woo*x|8 z_wfDu9tzcyCr*upG3-1HN@5N>$DC^VDbFsj%rPVU7q}g*S3k$N4_gl9J!4rl?64fitC$|QCv4Xb*GJs~XOy{tZ8`q3M3DuP z9$o29GK+$u0vfXYQlN7P9)AxICPBDJdGaI#NL~Slh*5G-5^tsTRu4)vHY#PcutRL| z6!S}->$7qS=0`i6`%!)FgIB{CXC-GkTvza1+=7MYX4*82YMVx@l6c0Bpq%c(~3qE!Xt|q0l$YYZBiM-xlQ4;oPKGWV!RU z<>rRG5_1cVRmoL6e%3Ep1-7>U$IGLB?i?P`-U1xa-U>UD^BISA4wa^PFR0rM&)*So z5|Sz#aHnL!|Gx~VfkE#WFg*%;DEq4{c=Lt#=4UUoEU1B%Kp^Y@yD-PZ1;UEMRMhoc z$9CCBR_B{>`vXX}AlZs!8E-ifg>fCE@L^}wHcea{dZQ(58yFfnFTN_!sCUJ_m zuu$cm7kmj?z6ylQCKP@jG^%{Q zG4SojrJsI#Myg3uBv4)hsJcP|X-cIERqK!h>SRUgff>0bPsOMPaCfvOH?(GJ{tO9p zss{>!e_c5(5zwkis&r9_^vlxSd85EzE9oZpwY2(ARUlR1{WLuPRr2g=Nw;5>0%Q6` zS(*U=uBL-{BS8~2*xeP<1f8crBb8^AXB0OUy(@A>f;}W*4=LOOoM%V53#>N(*6jS7 zZ%4oz9p(tn0)H_E=Y%RG4=a>en-dDxOTgF6$jc7GH~j~J zkXfR1$%Ar2PRpcqtGBvu^(_&yXKDA6I-8CU$i^&LB1$x_-Qthp?voM7RPP`5*t_#)t1^W!?!=Wdq3E_4gO9UpaO-j9Hle_$J^L2$1C~4viJ3{%hpazp6aM)y`Rkf2S5}Bv;m<1*t{{P1Uqz=L^y( zS<`4ooqS&g*>x+jdeB+ZX?l|cR6`2&)ViRnv7sq7x|>pyV3lljY=z_ba{1v ztPMI0t~Tj+)=G~;FvHG!rvCyVWr&c%U9GQyU80Z*(onH&i1q{_Wjte400M%I(>Gf) zx`NbH2knk#&>p(64z`6^y+LoyxG1llS&_1RWrVy$2CgWPE?jtF?&`Jqm)@Rx`K^e( zTq&(8j&Q;Ve+=eUyariI}t0gGv1kmt@kSTJN z8nE*L{|b)B#0ok7XYhxSV41+bj6?wvDy~-vFo3254V~*_%^o9YDxsqdpI8+3Xb0M@11iCwUHX9e% zKlglN@h4X!q#vpFwS`@~A#;le^CI;4K4?`pA7%~P!O6<&zW%ugZ_t}L8V75*q(P&gkygyY*+h)9haBBc=BcMAGvLB!t)B+8L0xD7bg zZK9;)?$7#``sDpfX{~eFiSi(b6@SsPUDK@U@Yf^$d`PI`9~Fim53;*O1q&6VAL^LL zA%BM&z!khXW<(KgVzZ$>4!?bXUL2i`V}ZgoBw}ZnR>R(w#87eNS8u4`ai3#84UN(? zwcx+0z|rQR2Fahf=b~yuvE6`U%^N1qSiW5t_S|uMB2o W>TQr)(n#vIu@9m?Z9w#^xBm@5GMb?P literal 0 HcmV?d00001 diff --git a/cert.pem b/cert.pem new file mode 100644 index 0000000..078c40a --- /dev/null +++ b/cert.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIFCTCCAvGgAwIBAgIUBWu1dbsZGPwTcg/pzECc8otDEr4wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI2MDQyMTEwMjgyMVoXDTI3MDQy +MTEwMjgyMVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA79zUZ4lGsVwv/1bJHq6xkKeszWDrC4qeHuiNOLX/7MCK +zk/GEcbRbTp1TYZg0+g+ixEmpaXa3jxhaYCVwMpinLfgpfL6FNmNPtxocXdNYm7K +s0+czmiaaBiutNluXC0az8QYt/BR00FwHOFuj3wX0olrUMWLhGELtRO921+9NF1W +GDYpnOo1smOHyIXuF/XboRQt2BlWEg6NKgXWUjqSDfzBan/aESlSFg0pLHzsYC2O +61hRn47LhWKhZ7tdSyLrSEVhnlXApjVDOsd7ZHUbY7/r3/tJ+DJXUTIAarpUnupO +SOZh1NtQPpg9wa2KPeWlF1yNEDkvLlER3kqB/nOqGhxh7u5VGXR9R9ZoFUsHsuLP +ru5d+UCWakBROSKc0K0vidGiZKqaiIfyTgpnvov+7nyL8y6QatQJ8bqCrPF91otn +WjWfr5Xr+iNyWnF/SP9Hoem693+wwL+7StmyfcS/1wChiqNFgceWbMK+0dGiqE9O +zoXQUuTmR3VCZ1pJaSZPqa4icmoYlAO99leqNE/SYvUk3LGs2pelDVIcfPSXgd1R +sbqt66EKMwwE2faQcMeNqNsFQXJ0bnJGKH7nZKevn/pkdG/F9G/KtyIbglqU7hM0 +7vIVKBbuu23fUfAFjvoTForjD/MGYoZguLbzccfGi9Dmd/Ge4es3ej25wnlrPO0C +AwEAAaNTMFEwHQYDVR0OBBYEFI861NylCN4wI9WNQD3+5U4YGAmyMB8GA1UdIwQY +MBaAFI861NylCN4wI9WNQD3+5U4YGAmyMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggIBADMWyaukkWDtyukXsRoaD3xikLSEUPaCU9QdQ1S9WRqOtAI4 +oqgngSEIYgyRyfkOMTY8LoQgjNXW+je0poVE4yPrdW6CA0VZrr4uWY/HvFn9+JL3 +5GhNiH8JjeJBnsVw3DA9fG+B0BhYmRxQqei9HDU8QSE0J9eaQUrNftXRoFOOQg3k +8rXj6BTZaIitsw/YHNSdnvDECqAxPam0BwqQXx/U0IadZ3AZvdJBf0uad0yAFkFU +7fJStheEEbjva14P4Tuthoh53uSyiTsZm1OBgJkauaXNhmjKijb9J+AfYYEV1lHL +R1TPm3p3KsZSjYLH8tkjO8ns+o81AmMGMzIrpM0qrlO4uSPjtz80a/eFe6LPIIgr +FKs0ZOWhuP7eA/o/TxPqQXoTHFDuAhxg37NfeveAtEGDW1yAcadkLyswDfCm/XUV +JJXbyySOaCw6sVOmbbl5LzVt+EJryM9YwCUQ15sBFwg6DXxxfDdNtLObjgaI+iL2 +5Zqs6DmXYt/YMhChIPDIZN047pIbxRLJjLwmcmynLlQLlwsbL3ljqN3aB6zp66sT +mBKdlHnSHZW+ExRR1eG3wW3i8GzfIt6t8Rd/YfV90edoQtsqEa5G62rkh+C6hDvm +HREqe6efjDZd0yppNtYjGrWH1LG9Caw1NgBH4XvO//rHN12GkxCiLRp24URU +-----END CERTIFICATE----- diff --git a/key.pem b/key.pem new file mode 100644 index 0000000..b5738d8 --- /dev/null +++ b/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +pvgmLr3zMMOd7hLpj+sXBsd3L6YLOw== +-----END PRIVATE KEY----- diff --git a/logs/server.log b/logs/server.log new file mode 100644 index 0000000000000000000000000000000000000000..4dc08ec0c336a9c825eff549f18dac284533baf0 GIT binary patch literal 3015 zcmeH}O-sWt7=S(RSG?>r5!0q0uI){R)1kQGDjsBql0_S+NleoD_id)Qj1>mLZg~T_ zyq`R$XZARq7hq#)DrM*zG*ug_Kq^6~*6@mPHcsNzVD?w}QZd8$JG==6m6Q!5m0^N| zwi8;3oYL#VG!XG28)~Rq_q<_5C=ROS+>Y+1)y7C&1VM5K7Id?YVJVN*?L){-1X`UnzT*C17ri7ro&$Jru%5o84gohA?A { - audioChunks.push(e.data); + const source = audioContext.createMediaStreamSource(audioStream); + scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1); + + scriptProcessor.onaudioprocess = (e) => { + if (isRecording) { + recordedBuffers.push(e.inputBuffer.getChannelData(0).slice()); + } }; - mediaRecorder.onstop = async () => { - const audioBlob = new Blob(audioChunks, { type: 'audio/webm' }); - audioChunks = []; - await sendAudio(audioBlob); - }; + source.connect(scriptProcessor); + scriptProcessor.connect(audioContext.destination); return true; } catch (e) { @@ -371,13 +421,12 @@ // 开始录音 async function startRecording() { - if (!mediaRecorder) { + if (!audioContext) { const success = await initAudio(); if (!success) return; } - audioChunks = []; - mediaRecorder.start(); + recordedBuffers = []; isRecording = true; recordBtn.classList.add('recording'); @@ -390,16 +439,29 @@ // 停止录音 function stopRecording() { - if (mediaRecorder && isRecording) { - mediaRecorder.stop(); + if (isRecording) { isRecording = false; + // 合并所有缓冲区 + const totalLength = recordedBuffers.reduce((acc, buf) => acc + buf.length, 0); + const mergedBuffer = new Float32Array(totalLength); + let offset = 0; + for (const buf of recordedBuffers) { + mergedBuffer.set(buf, offset); + offset += buf.length; + } + + // 创建 WAV 文件 + const wavBlob = createWavFile(mergedBuffer, 16000); + recordBtn.classList.remove('recording'); recordBtn.querySelector('.icon').textContent = '🎤'; recordBtn.querySelector('.text').textContent = '点击录音'; recordStatus.textContent = '处理中...'; recordStatus.classList.remove('recording'); waveform.style.display = 'none'; + + sendAudio(wavBlob); } } @@ -409,7 +471,7 @@ showLoading(); const formData = new FormData(); - formData.append('audio', audioBlob, 'recording.webm'); + formData.append('audio', audioBlob, 'recording.wav'); if (conversationId) { formData.append('conversation_id', conversationId); }