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

如何在setInterval中使用SpeechSynthesis?Safari兼容问题

Safari中setInterval结合语音合成失效的解决方案

问题原因

Safari的安全策略对speechSynthesis.speak()的触发有严格限制:只有直接由用户交互(如点击、触摸)启动的上下文才能调用语音合成。而setInterval的回调函数属于异步定时器任务,会脱离初始的用户交互上下文,被Safari的安全机制拦截,导致语音合成无法执行。

修复方案

放弃使用setInterval,改用递归式setTimeout,同时借助SpeechSynthesisUtterance的end事件,在每次语音合成结束后再调度下一次任务。这种方式能确保每次语音合成的调用都处于合法的上下文链条中,规避Safari的安全限制。

修改后的代码

HTML:

<button type="button" id="speakBtn" disabled>Speak</button>

JavaScript:

if ('speechSynthesis' in window) {
  speechSynthesis.cancel();
  speechSynthesis.getVoices();
  speakBtn.disabled = false;
}

const speakLoop = () => {
  const utter = new SpeechSynthesisUtterance();
  utter.text = "Hello world";
  // 语音合成结束后,调度下一次任务
  utter.addEventListener('end', () => {
    setTimeout(speakLoop, 5000);
  });
  speechSynthesis.speak(utter);
};

const speak = () => {
  // 清除已有任务,避免重复触发导致语音叠加
  speechSynthesis.cancel();
  speakLoop();
};

speakBtn.addEventListener('click', speak);

补充说明

  • 每次启动新的语音循环前调用speechSynthesis.cancel(),可以避免多个语音任务堆积播放。
  • 递归setTimeout相比setInterval更可靠:它会等待上一次语音合成完成后再启动下一次,不会出现定时器任务与语音播放不同步的问题,同时更适配Safari的安全规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 15:00:53