From a86b4ba404162abca936cb79d0584713e995b333 Mon Sep 17 00:00:00 2001 From: 1600822305 <1600822305@qq.com> Date: Fri, 11 Apr 2025 03:37:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=20=E8=AF=AD?= =?UTF-8?q?=E9=9F=B3=E9=80=9A=E8=AF=9D=E5=8A=9F=E8=83=BD=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=9C=8D=E5=8A=A1=E5=B9=B6=E6=9B=B4=E6=96=B0=E4=BA=86?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/assets/asr-server/index.html | 27 + src/renderer/src/assets/asr-server/server.js | 7 + .../src/components/VoiceCallButton.tsx | 55 ++ .../src/components/VoiceCallModal.tsx | 263 +++++++ .../src/components/VoiceVisualizer.tsx | 97 +++ src/renderer/src/i18n/locales/en-us.json | 15 + src/renderer/src/i18n/locales/zh-cn.json | 15 + .../src/pages/home/Inputbar/Inputbar.tsx | 2 + src/renderer/src/services/ASRService.ts | 53 +- src/renderer/src/services/VoiceCallService.ts | 656 ++++++++++++++++++ 10 files changed, 1173 insertions(+), 17 deletions(-) create mode 100644 src/renderer/src/components/VoiceCallButton.tsx create mode 100644 src/renderer/src/components/VoiceCallModal.tsx create mode 100644 src/renderer/src/components/VoiceVisualizer.tsx create mode 100644 src/renderer/src/services/VoiceCallService.ts diff --git a/src/renderer/src/assets/asr-server/index.html b/src/renderer/src/assets/asr-server/index.html index ac0531d0ce..c049cb2b21 100644 --- a/src/renderer/src/assets/asr-server/index.html +++ b/src/renderer/src/assets/asr-server/index.html @@ -64,6 +64,9 @@ startRecognition(); } else if (data.type === 'stop') { stopRecognition(); + } else if (data.type === 'reset') { + // 强制重置语音识别 + forceResetRecognition(); } else { console.warn('[Browser Page] Received unknown command type:', data.type); } @@ -362,6 +365,30 @@ updateStatus("识别未运行。"); } } + + function forceResetRecognition() { + console.log('[Browser Page] Force resetting recognition...'); + updateStatus("强制重置语音识别..."); + + // 先尝试停止当前的识别 + if (recognition) { + try { + recognition.stop(); + } catch (e) { + console.error('[Browser Page] Error stopping recognition during reset:', e); + } + } + + // 强制设置为null,丢弃所有后续结果 + recognition = null; + + // 通知服务器已重置 + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type: 'status', message: 'reset_complete' })); + } + + updateStatus("语音识别已重置,等待新指令。"); + } diff --git a/src/renderer/src/assets/asr-server/server.js b/src/renderer/src/assets/asr-server/server.js index 7b3d77d9f2..677124ce97 100644 --- a/src/renderer/src/assets/asr-server/server.js +++ b/src/renderer/src/assets/asr-server/server.js @@ -124,6 +124,13 @@ wss.on('connection', (ws) => { } else { console.log('[Server] Cannot relay STOP: Browser not connected') } + } else if (data.type === 'reset' && ws === electronConnection) { + if (browserConnection && browserConnection.readyState === WebSocket.OPEN) { + console.log('[Server] Relaying RESET command to browser') + browserConnection.send(JSON.stringify({ type: 'reset' })) + } else { + console.log('[Server] Cannot relay RESET: Browser not connected') + } } // 浏览器发送识别结果 else if (data.type === 'result' && ws === browserConnection) { diff --git a/src/renderer/src/components/VoiceCallButton.tsx b/src/renderer/src/components/VoiceCallButton.tsx new file mode 100644 index 0000000000..00d784b4ed --- /dev/null +++ b/src/renderer/src/components/VoiceCallButton.tsx @@ -0,0 +1,55 @@ +import React, { useState } from 'react'; +import { Button, Tooltip } from 'antd'; +import { PhoneOutlined, LoadingOutlined } from '@ant-design/icons'; +import { useTranslation } from 'react-i18next'; +import VoiceCallModal from './VoiceCallModal'; +import { VoiceCallService } from '../services/VoiceCallService'; + +interface Props { + disabled?: boolean; + style?: React.CSSProperties; +} + +const VoiceCallButton: React.FC = ({ disabled = false, style }) => { + const { t } = useTranslation(); + const [isModalVisible, setIsModalVisible] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const handleClick = async () => { + if (disabled || isLoading) return; + + setIsLoading(true); + try { + // 初始化语音服务 + await VoiceCallService.initialize(); + setIsModalVisible(true); + } catch (error) { + console.error('Failed to initialize voice call:', error); + window.message.error(t('voice_call.initialization_failed')); + } finally { + setIsLoading(false); + } + }; + + return ( + <> + +