From ab427d2fdc869b357475652771f4cca494e11d64 Mon Sep 17 00:00:00 2001 From: guoqingshan Date: Sun, 2 Aug 2026 11:56:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E6=9C=97=E8=AF=BB=E8=AF=AD=E9=9F=B3=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E4=B8=8E=E8=AF=AD=E8=A8=80=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- speech.js | 78 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/speech.js b/speech.js index 92197b2..2a4232a 100644 --- a/speech.js +++ b/speech.js @@ -1,32 +1,72 @@ -function initSpeech() { +var speechVoices = []; +var speechVoicesLoaded = false; + +function refreshSpeechVoices() { if (!window.speechSynthesis) return; var voices = window.speechSynthesis.getVoices(); - if (voices.length > 0) return; - window.speechSynthesis.onvoiceschanged = function() {}; -} - -function speakText(text, lang) { - if (!text) return; - if (!window.speechSynthesis) { return; } - if (window.speechSynthesis.getVoices().length === 0) { - window.speechSynthesis.onvoiceschanged = function() { - doSpeak(text, lang); - window.speechSynthesis.onvoiceschanged = null; - }; - window.speechSynthesis.getVoices(); - return; + if (voices && voices.length) { + speechVoices = voices; + speechVoicesLoaded = true; } - doSpeak(text, lang); + return speechVoices; } -function doSpeak(text, lang) { - window.speechSynthesis.cancel(); +function pickSpeechVoice(lang) { + refreshSpeechVoices(); + var target = lang.toLowerCase(); + var exact = speechVoices.find(function(voice) { + return String(voice.lang || '').toLowerCase() === target; + }); + if (exact) return exact; + var prefix = target.split('-')[0]; + return speechVoices.find(function(voice) { + return String(voice.lang || '').toLowerCase().split('-')[0] === prefix; + }) || null; +} + +function buildSpeechUtterance(text, lang) { var utterance = new SpeechSynthesisUtterance(text); var langMap = { 'es': 'es-ES', 'en': 'en-US', 'zh': 'zh-CN' }; utterance.lang = langMap[lang] || lang; + var voice = pickSpeechVoice(utterance.lang); + if (voice) utterance.voice = voice; utterance.rate = 0.9; utterance.pitch = 1; - window.speechSynthesis.speak(utterance); + return utterance; +} + +function doSpeak(text, lang) { + if (!window.speechSynthesis || !text) return; + window.speechSynthesis.cancel(); + window.speechSynthesis.speak(buildSpeechUtterance(text, lang)); +} + +function speakText(text, lang) { + if (!text || !window.speechSynthesis) return; + refreshSpeechVoices(); + if (speechVoicesLoaded) { + doSpeak(text, lang); + return; + } + + var attempts = 0; + var timer = setInterval(function() { + attempts++; + refreshSpeechVoices(); + if (speechVoicesLoaded || attempts >= 8) { + clearInterval(timer); + doSpeak(text, lang); + } + }, 80); + window.speechSynthesis.getVoices(); +} + +function initSpeech() { + if (!window.speechSynthesis) return; + refreshSpeechVoices(); + window.speechSynthesis.onvoiceschanged = function() { + refreshSpeechVoices(); + }; } if (document.readyState === 'complete') initSpeech();