fix: 优化移动端朗读语音加载与语言匹配

This commit is contained in:
guoqingshan
2026-08-02 11:56:29 +08:00
parent 75fc9cc7a4
commit ab427d2fdc
+59 -19
View File
@@ -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();