From 2c4535e57e2fe72d1d6419b186fd0aecc9cfd9b9 Mon Sep 17 00:00:00 2001 From: Nan Kyung Lee Date: Tue, 24 Mar 2026 15:56:35 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=A4=91=EA=B5=AD=EC=96=B4=20TTS=20?= =?UTF-8?q?=EB=81=8A=EA=B9=80=20=ED=95=B4=EA=B2=B0=20=E2=80=94=20Chrome=20?= =?UTF-8?q?pause/resume=20keepalive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/korea/OpsGuideModal.tsx | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/korea/OpsGuideModal.tsx b/frontend/src/components/korea/OpsGuideModal.tsx index 559a763..fd0fd58 100644 --- a/frontend/src/components/korea/OpsGuideModal.tsx +++ b/frontend/src/components/korea/OpsGuideModal.tsx @@ -148,15 +148,26 @@ export function OpsGuideModal({ ships, onClose, onFlyTo, onRouteSelect }: Props) window.speechSynthesis.cancel(); const utter = new SpeechSynthesisUtterance(text); utter.lang = 'zh-CN'; - utter.rate = 0.85; + utter.rate = 0.8; + utter.pitch = 1.0; utter.volume = 1; - // Try to find a Chinese voice const voices = window.speechSynthesis.getVoices(); - const zhVoice = voices.find(v => v.lang.startsWith('zh')) || voices.find(v => v.lang.includes('CN')); + const zhVoice = voices.find(v => v.lang === 'zh-CN') || voices.find(v => v.lang.startsWith('zh')); if (zhVoice) utter.voice = zhVoice; - utter.onstart = () => setSpeakingIdx(idx); - utter.onend = () => setSpeakingIdx(null); - utter.onerror = () => setSpeakingIdx(null); + // Chrome bug workaround: pause/resume keepalive to prevent cutoff + let keepAlive: ReturnType | null = null; + utter.onstart = () => { + setSpeakingIdx(idx); + keepAlive = setInterval(() => { + if (window.speechSynthesis.speaking && !window.speechSynthesis.paused) { + window.speechSynthesis.pause(); + window.speechSynthesis.resume(); + } + }, 5000); + }; + const cleanup = () => { setSpeakingIdx(null); if (keepAlive) clearInterval(keepAlive); }; + utter.onend = cleanup; + utter.onerror = cleanup; window.speechSynthesis.speak(utter); }, []);