Chrome中Speech Synthesis切换自定义语音后朗读中途停止求助
问题描述
- 使用自定义语音
voices[4]朗读长文本时,仅朗读10-15秒就停止 - 播放/暂停按钮可从停止位置恢复朗读,功能正常
- 使用默认语音时能完整朗读全文
- 当前在Chrome浏览器中使用该功能
用户提供的原始代码:
var isSpeaking = false; var paused = false; var speech; document.getElementById('readButton').addEventListener('click', function() { var icon = document.getElementById('playButton'); if (icon.classList.contains('fa-circle-play') && !paused) { icon.classList.remove("fa-circle-play"); icon.classList.add("fa-circle-pause"); startSpeaking(); } else if (icon.classList.contains('fa-circle-play') && paused) { icon.classList.remove("fa-circle-play"); icon.classList.add("fa-circle-pause"); resumeSpeaking(); } else if (icon.classList.contains('fa-circle-pause')) { icon.classList.remove("fa-circle-pause"); icon.classList.add("fa-circle-play"); stopSpeaking(); } }); function startSpeaking() { if (!isSpeaking) { var mainContent = document.getElementById('articleBody'); var textToRead = mainContent.innerText; if ('speechSynthesis' in window) { speech = new SpeechSynthesisUtterance(textToRead); speech.lang = 'en-EN'; speech.volume = 1; speech.rate = 1; speech.pitch = 1.1; speechSynthesis.onvoiceschanged = function() { var voices = window.speechSynthesis.getVoices(); speech.voice = voices[4]; window.speechSynthesis.speak(speech); isSpeaking = true; }; } else { alert('Browser-ul tău nu suportă funcția de vorbire text!'); } } } function stopSpeaking() { if (isSpeaking) { window.speechSynthesis.pause(); isSpeaking = false; paused = true; } } function resumeSpeaking() { if (!isSpeaking && paused) { window.speechSynthesis.resume(); isSpeaking = true; paused = false; } }
问题原因
- 代码在
startSpeaking函数内绑定speechSynthesis.onvoiceschanged事件,该事件可能被Chrome多次触发,每次触发都会重新调用speak,直接中断正在进行的朗读 - 语音列表加载完成前就创建了
SpeechSynthesisUtterance实例,自定义语音无法正确绑定,导致朗读提前终止
修正方案
修正后的代码
var isSpeaking = false; var paused = false; var speech; var voices = []; // 页面加载时预先监听语音列表变化,缓存可用语音 window.speechSynthesis.onvoiceschanged = function() { voices = window.speechSynthesis.getVoices(); // 可选:打印语音列表确认目标语音索引是否正确 // console.log(voices); }; document.getElementById('readButton').addEventListener('click', function() { var icon = document.getElementById('playButton'); if (icon.classList.contains('fa-circle-play') && !paused) { icon.classList.remove("fa-circle-play"); icon.classList.add("fa-circle-pause"); startSpeaking(); } else if (icon.classList.contains('fa-circle-play') && paused) { icon.classList.remove("fa-circle-play"); icon.classList.add("fa-circle-pause"); resumeSpeaking(); } else if (icon.classList.contains('fa-circle-pause')) { icon.classList.remove("fa-circle-pause"); icon.classList.add("fa-circle-play"); stopSpeaking(); } }); function startSpeaking() { // 先确认语音列表已加载完成 if (!isSpeaking && voices.length > 0) { var mainContent = document.getElementById('articleBody'); var textToRead = mainContent.innerText; if ('speechSynthesis' in window) { speech = new SpeechSynthesisUtterance(textToRead); speech.lang = 'en-EN'; speech.volume = 1; speech.rate = 1; speech.pitch = 1.1; // 直接使用缓存的语音列表设置自定义语音 speech.voice = voices[4]; window.speechSynthesis.speak(speech); isSpeaking = true; } else { alert('你的浏览器不支持文本朗读功能!'); } } else if (!voices.length) { alert('语音列表尚未加载完成,请稍后重试!'); } } function stopSpeaking() { if (isSpeaking) { window.speechSynthesis.pause(); isSpeaking = false; paused = true; } } function resumeSpeaking() { if (!isSpeaking && paused) { window.speechSynthesis.resume(); isSpeaking = true; paused = false; } }
修改说明
- 全局缓存语音列表,页面加载时就监听
onvoiceschanged事件,避免重复绑定导致的多次朗读触发 - 在
startSpeaking中先检查语音列表是否加载完成,确保能正确获取到目标自定义语音 - 直接在创建朗读实例后设置语音再调用
speak,保证语音绑定生效
内容的提问来源于stack exchange,提问作者Lavanda
相关产品推荐
相关产品推荐

