You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置Speech Synthesis特定语音,解决默认语音干扰及首次点击失效问题

解决SpeechSynthesis首次点击语音不生效的问题

问题根源在于浏览器加载语音资源是异步的,首次调用getVoices()时,语音列表还没完全加载完成,导致你指定的voices[9]可能不存在,只能默认使用对应语言的兜底语音。第二次点击时语音列表已经加载完毕,所以能正确选中目标语音。

解决步骤:

  • 监听voiceschanged事件,等语音列表加载完成后缓存起来,避免每次点击临时获取
  • 点击按钮时直接用缓存好的语音列表,确保首次点击就能拿到正确的语音

修改后的代码:

// 缓存加载完成的语音列表
let cachedVoices = [];

// 监听语音列表加载完成事件
window.speechSynthesis.onvoiceschanged = () => {
  cachedVoices = window.speechSynthesis.getVoices();
};

function speakTTS() {
  // 先检查语音列表是否就绪
  if (cachedVoices.length === 0) {
    // 手动触发一次获取,兼容部分浏览器的延迟加载逻辑
    cachedVoices = window.speechSynthesis.getVoices();
    if (cachedVoices.length === 0) {
      alert('语音资源还没加载好,请稍后再试');
      return;
    }
  }

  const message = new SpeechSynthesisUtterance();
  message.text = "Please get me a bottle of water, thank you.";
  message.volume = 1;
  message.rate = 1.1;
  // 使用缓存的语音列表
  message.voice = cachedVoices[9];
  message.lang = 'en-GB';
  window.speechSynthesis.speak(message);
}
<button onClick="speakTTS()">Speak</button>

额外优化建议:

不要直接用索引voices[9]指定语音,不同浏览器的语音列表顺序可能不一致,建议通过语音的lang或name属性精准匹配,比如:

// 精准查找en-GB的目标语音
const targetVoice = cachedVoices.find(voice => voice.lang === 'en-GB' && voice.name.includes('George'));
if (targetVoice) {
  message.voice = targetVoice;
}

内容的提问来源于stack exchange,提问作者rich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:25:56