From 8d5d1ce48d7599222605b53d49f96a460346f693 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Fri, 5 Sep 2025 21:31:14 +0800 Subject: [PATCH] 'commit' --- dsLightRag/KeDaXunFei/XunFeiAudioEvaluator.py | 29 +++--- .../XunFeiAudioEvaluator.cpython-310.pyc | Bin 7221 -> 7295 bytes dsLightRag/Routes/XunFeiRoute.py | 26 ++++-- .../__pycache__/XunFeiRoute.cpython-310.pyc | Bin 4276 -> 4358 bytes .../static/XunFei/audio_evaluation.html | 5 -- .../static/XunFei/js/audio_evaluation.js | 84 ++++++++++++------ 6 files changed, 89 insertions(+), 55 deletions(-) diff --git a/dsLightRag/KeDaXunFei/XunFeiAudioEvaluator.py b/dsLightRag/KeDaXunFei/XunFeiAudioEvaluator.py index a922dd35..84057fe7 100644 --- a/dsLightRag/KeDaXunFei/XunFeiAudioEvaluator.py +++ b/dsLightRag/KeDaXunFei/XunFeiAudioEvaluator.py @@ -18,12 +18,13 @@ from Config.Config import XF_APPID, XF_APISECRET, XF_APIKEY class XunFeiAudioEvaluator: """讯飞语音评测类""" - def __init__(self, appid, api_key, api_secret, audio_file): + def __init__(self, appid, api_key, api_secret, audio_file, language): self.appid = appid self.api_key = api_key self.api_secret = api_secret self.audio_file = audio_file - self.host_url = "ws://ise-api.xfyun.cn/v2/open-ise" + self.language = language + self.host_url = "wss://ise-api.xfyun.cn/v2/open-ise" self.websocket_url = "" self.evaluation_results = {} @@ -60,29 +61,29 @@ class XunFeiAudioEvaluator: print(f"Received message: {message}") data = json.loads(message) status = data["data"]["status"] - + if status == 2: # 解析评测结果 xml_data = base64.b64decode(data["data"]["data"]) xml_content = xml_data.decode("utf-8") #print(xml_content) - + # 解析XML并提取得分信息 self.parse_evaluation_results(xml_content) ws.close() - + def on_error(self, ws, error): """错误处理""" print(f"Error: {error},{ws}") - + def on_close(self, ws, reason, res): """连接关闭处理""" print(f"WebSocket connection closed,{ws}") - + def on_open(self, ws): """连接建立处理""" print(f"WebSocket connection opened,{ws},ws连接建立成功...") - + # 发送初始参数 send_dict = { "common": { @@ -93,7 +94,7 @@ class XunFeiAudioEvaluator: "rstcd": "utf8", "sub": "ise", "group": "pupil", - "ent": "en_vip", + "ent": "zh_cn" if self.language == "chinese" else "en_vip", "tte": "utf-8", "cmd": "ssb", "auf": "audio/L16;rate=16000", @@ -106,7 +107,7 @@ class XunFeiAudioEvaluator: } } ws.send(json.dumps(send_dict)) - + # 发送音频数据 with open(self.audio_file, "rb") as file_flag: while True: @@ -115,12 +116,12 @@ class XunFeiAudioEvaluator: # 发送最后一帧 my_dict = { "business": { - "cmd": "auw", - "aus": 4, + "cmd": "auw", + "aus": 4, "aue": "lame" }, "data": { - "status": 2, + "status": 2, "data": str(base64.b64encode(buffer).decode()) } } @@ -157,7 +158,7 @@ class XunFeiAudioEvaluator: self.evaluation_results = { 'accuracy_score': float(read_chapter.get('accuracy_score', 0)), 'fluency_score': float(read_chapter.get('fluency_score', 0)), - 'integrity_score': float(read_chapter.get('integrity_score', 0)), + 'completeness_score': float(read_chapter.get('integrity_score', 0)), # 修复字段名 'standard_score': float(read_chapter.get('standard_score', 0)), 'total_score': float(read_chapter.get('total_score', 0)), 'word_count': int(read_chapter.get('word_count', 0)), diff --git a/dsLightRag/KeDaXunFei/__pycache__/XunFeiAudioEvaluator.cpython-310.pyc b/dsLightRag/KeDaXunFei/__pycache__/XunFeiAudioEvaluator.cpython-310.pyc index aaa495bec1a68416be436b9b31a430c5e173623d..baa03fe9b1a1fca66344d23403a330f169daf8ff 100644 GIT binary patch delta 1862 zcmZuy-ES0C6rVdYJ3IR^&~3Nvw%gi5L0FKj&{7ZyhLA{tP&ExfAz_&Ay=<56SMQyr zuuSEF1TYZAUO(d+w`xel1Y@c`Kw|hCOnjNd2OrwvgMWjbGcC2Y&Srjd?mg%H?z#7z zbN8o%e;>3emK9atIlk~{;_Dx*BkEfQ4p$zORd|oVD~16);wiS`ser`O098*1)VvU& zPEi}8s5J@-V3;anN=6&4Z=Dvhp$-sJK2djti%vOTbMkUY9o%O4x?shNJO=DMj$k2d zLf8!Ot-_OXzjoSafq_Bh-_y8iq0DuFjLF-iWt`a81B0^>TFALJbzFxh(IS9$ko-iR zl^J(jW;-=^!mjaR-~78q580Cf?P$jILsecVyS{!&RLXv+SaGP}JJB;TJ~B*Mu0k2# zC4UX?NVVatIxYNgi3#E48Q%jlJS!7sI=yb$Xr*kgSiLNdn;-6d5lk~0M-D!ML?Om` zg|83S1iwJ>nv6$g4;)4>eT|pFnS+69oQePQ%@r$xy)J)?93#)muIRvZPr0O0b5iA< zG*TusN@FxmExL(rrY(&qP0&`_)=+7(q0OisX=<+C40-AtnIlAT4e$=r_8aQ^r)RW? z;%QBjcFvI*-P6T+nxb96)7{W$+Ksr;X3W#)NHadC+#msGPeYx#9$F<0t&m#HO|%#3 z%L72syF$^sfuff_NBbH&MVgJFAxl59OpTmT=oVekl^YrXX-wIxh`ZCE!C&-k0G!Nh zl_N2)E1a7sl$l_Ds6Jum%D%zM_T@sAr{v?Olt5wFk!61Jv`SAE3^>1Do z&1~ja8p~aPWshA^rhG4oAzCX{g|AnttQ<6kug_Z1ZCIW>gRm=ba0?~akSH=%%@`}i zBD2=+)ViV!LvbP1n4GdYNXz_fYhFERBhLloX@wnEi_C?F5yBR^3TJ#AwK)WezyRv8 z?BF282zEIJCA~_(bMi{dQ0&sG%cT6dOZm^+)HvWk%D^y2#fMmB9;7a zoO~EGAJ1P+JWzKBOXHE&we0Xk-U(7I0kClE=F;55g-7=ne)(kK_RT~6+?J!s?gJNA z4IbWI{OHHE2F^3pV)GWbuT_o9FO!}7aEAf;;-}v)+`IqutM3-?%q~6t0?2XSuhuj` z&;?&G;05_KNeOJBefy3{(D5;Vx|;3hcm{R#P=8(R-&t2PQK*GhG?ZmF6Z{%j{4OUt|7tk|5@5=_h_}s zH(2|r<+KJ{!@`qh*OAzoT*^1Q+Q?JMy1a88xB!xFpusszIDZELgX8xQ{^bcIyv%t7 z0MAk2~K& zW!Mw4jkzT|ZRhu4|8R zu@x+0o6LkQYsGjGr<7fe+9R{!&-eC2Xhv5YViytxxDbw5S!WpXl;aS@xVXqET3ata zYfH+P%`-zUAdB%7OHgpzbxOW2xch%xs`exDfq9UmcEY6zdB5Vz7 zW{EkE|5v1Zn(p&jkN<$ zYEEYzUf46|BXwhe%tsfrX`(pOb96HBm@@#JQ%D+{k24GDOFckgEmK&lC@i*)t)DX( z(yT5GSvDZcnf_sobsCzXP3r_&$Fu>>JzoV6zVEG`gviV1PcP1|{lk z+=(~n-glAsJ%m#TS%gsp8v)a5(Z2qEsK?`_JO>d!$rzPCHV;NmW8f&l*p96XXiJhzx8owbQqht6i$(Qc`t+LMaz~Ppad|bl zanl(1#G3#$+Ses;L27hQSB-XUuF*^c1b}skqWmM-*Qf50kXtDhZE;R5flms;gMg7B zD`$)D*wZtY``aw?L*ryyFBvRC%%e*LNAzQiyLnM4dj+So^8AY`MEokhYk$!EJha4K zgaZgCY}T7@irg$Lsa_D{&kraT4dFNu5ZgP&jZw0a0kADk@D&AVP|qzT?Efv7^~Z zT&h_Ta8-$e6{MBQp?uia-cUGI;#7{PLgKbp#34TbAtg;4B$mnJb$Qf zV4)cCqih76=H0z-W;#u?#_2Y1u%dUCn@q(h7lQb~OS~rOgDIb*2ftK_CV;#9L&4Zr7zU z+zxfnJc7g(Ra*XKO*J!IO>8DzTbbK10;4VL#zm@~?x1#$jLX>WMsJ6l z_5KNQ6K+yu+I`Z}y@;&nZ|6FwiQSYKkSQq0giP|^WU@WjK`_=bme8W=_Zc#f82TE2 zmd40cap$7Qw})X|WM#UEAE57uz9vkFktW(f{BM!j7;P8i`^rj_|4av-+rlKAdwx1h zwL(jXs*Qw%oBlklt@YZ#4OE;y_{D7Dn~l;=k@yr?l?mokXS-ak++N^Vy-z-AtR8A` zsNO47*?S8ienBDricS|*Du(|j@YnUBe(x)5gcQTx&(?^!Oj&JZr?TapT0h`1@B7%y zJBBi4zER&|wPo93qIPS&RI9P76ELT=xz(tESPxj4mo^zM3AP+-@QPpocf2RDIXvej z?dHT~<>=FD{Z^^!_{LUAtoxMRt~kOe_V7z*xAVxpG&ry8NTbZ()ga1tO4aR>sB=E& zo!avs-BT*rBQcZM*bJ%Yt|=oyOp?G>Fm0TFYSR2)BtbDH6caV+k!g{TMtWMu#CnF! zV>{~Y$Md;VB!jcW!bAtQanFglM~?W)!Q*%Vzj0q#JNhG5{-!>cp72#gi?e>DT3=hM z)YkY1it|O4d_z>!hAeowBh$CBT?wxngsgC7R((}hzyT@9+Y>W<*!ny+XcT4RE* odKXet_(Shz>dgYh#*y;;hY)hAx;P;Qc}l|Mm{9x3T+85p0Z?o_Pyhe` delta 1228 zcmZ8g&u<$=6rPz~&#u?&wVgO|lIC~XB%4T32$euksRgNODHNm}B0{4m>f59ajvb9B zNr}d!)FB+er=n5{CgxZID;tO_;Nf=H(H?`+A1t?Ap;#vuM@hO-ZAKI zcrj=#(|Ha(fepRE2=pQP5d(-p#8BYOdvF|1Y(~m-dNdfU`Y>FhFcOT+GZ+Pb(?os@ z=p^yS{?KwR`Bpu8_Vt}R^pu%dX+h@q+namee6aV?`+M7;?QXrd`^C56ZsaEI2o>*} zwe*_iNa3vC@n=Nw9wp>my8e}-Kv$`7B>@Hom=$(|Dib2ewKq84U)nmGm_Wx;_e%us>;P~U!aH3*N5soJYUMcxb5*s(>HEOOAe|YDv zU7^n|El>EY&LPMJGN|+7%KUux+9mM>UbuKto0DjK^M8bRCj80iZC^1kdH?$#*PS=7 z6!J32%NfV#;XS8!NOWLong{vW)$Fowi0AcQFKD9^0zV}Z^4O=eJG>PeIyl|k6z zo}s71Nw+-uBIfHnSGY2lE7r~BIeE3tgKOEMEcz)ip?AO^4)+T8-HFs$T^tQo=W;7^ zvLM9i@Lc@D#wxPxI&*F2Qrkc@=cM6LhuXCJh;dFiYG5p{F00ItMJKXZy&t zbS$Uty z%wXt`*R5P(VIiAe5U*k^UPDtiWp*hLFNe#CSLjRO4~dVTp42oKg%ueH(WVQBwK?CY zUM>`+7}T+DST_~|DQ3d0 -
- - -
-
diff --git a/dsLightRag/static/XunFei/js/audio_evaluation.js b/dsLightRag/static/XunFei/js/audio_evaluation.js index ac6b3f2d..ae652a1a 100644 --- a/dsLightRag/static/XunFei/js/audio_evaluation.js +++ b/dsLightRag/static/XunFei/js/audio_evaluation.js @@ -12,19 +12,20 @@ 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.'; - } -}); +// 移除语言切换事件监听 +// languageSelect.addEventListener('change', () => { +// if (languageSelect.value === 'chinese') { +// textInput.value = '窗前明月光,疑是地上霜。'; +// } else { +// textInput.value = 'Nice to meet you.'; +// } +// }); -// 页面加载时自动填充中文示例 -window.addEventListener('load', () => { - textInput.value = '窗前明月光,疑是地上霜。'; - stopBtn.disabled = true; -}); +// 移除页面加载事件监听 +// window.addEventListener('load', () => { +// textInput.value = '窗前明月光,疑是地上霜。'; +// stopBtn.disabled = true; +// }); // 开始录音 recordBtn.addEventListener('click', async () => { @@ -46,15 +47,29 @@ recordBtn.addEventListener('click', async () => { } }); - mediaRecorder = new MediaRecorder(stream); - audioChunks = []; - - mediaRecorder.ondataavailable = (event) => { - audioChunks.push(event.data); + // 检测浏览器支持的录制格式 + 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' }); + audioBlob = new Blob(audioChunks, { type: 'audio/webm' }); // 与录制格式匹配 statusDiv.textContent = '录音完成,正在自动提交评测...'; submitEvaluation(); // 停止所有音轨以释放麦克风 @@ -104,11 +119,12 @@ async function submitEvaluation() { return; } - if (!textInput.value.trim()) { - statusDiv.textContent = '请输入评测文本内容'; - statusDiv.className = 'status error'; - return; - } + // 移除文本验证 + // if (!textInput.value.trim()) { + // statusDiv.textContent = '请输入评测文本内容'; + // statusDiv.className = 'status error'; + // return; + // } try { statusDiv.textContent = '正在提交评测...'; @@ -117,7 +133,8 @@ async function submitEvaluation() { const formData = new FormData(); formData.append('audio_file', audioBlob, 'recording.webm'); formData.append('language', languageSelect.value); - formData.append('text', textInput.value.trim()); + // 移除文本参数 + // formData.append('text', textInput.value.trim()); formData.append('group', 'adult'); formData.append('check_type', 'common'); formData.append('grade', 'middle'); @@ -168,20 +185,33 @@ function displayResults(results) { 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 += '
'; // 显示单词级评分 if (results.words && results.words.length > 0) { html += '

单词评分:

    '; results.words.forEach(word => { - html += `
  • ${word.content}: ${word.score.toFixed(4)}
  • `; + // 为单词评分添加空值检查 + const score = word.score !== undefined ? word.score.toFixed(4) : '无'; + html += `
  • ${word.content}: ${score}
  • `; }); html += '
'; }