语音合成 API 阻塞主线程

Speech Synthesis API blocks main thread

我正在使用语音合成 API 来发音一系列不同的单词。当通过 canvas 说出这些词时,我的应用程序会为词的输入和输出设置动画。我意识到当我执行一个新的话语时:

var msg = new SpeechSynthesisUtterance(word);
window.speechSynthesis.speak(msg);

口语似乎阻塞了主线程,暂时停止了动画。每次我打电话给 window.speechSynthesis.speak();.

时都会发生这种情况

有没有办法在 Javascript 中的单独线程上进行语音合成 运行,这样它就不会干扰我在主线程上的动画?

(我主要在 Chrome 中对此进行测试)

我会使用 setTimeout 来伪造一个异步调用:

var msg = new SpeechSynthesisUtterance(word);
setTimeout(function() { window.speechSynthesis.speak(msg); }, 1);

我必须承认我对此不确定。

这里要遵循的一种方法是使用一个工作线程来播放与文本消息相对应的音频。

网络工作者无权访问 window 对象。所以我们不能直接在worker内部调用window.speechSythesis.speak方法。

text-to-speech library from Francois Laberge 实现的一项很好的工作是

  1. 将要朗读的文本发送到工作线程。
  2. 工作线程然后将此文本转换为音频 (WAV) 文件,return 主线程将 WAV 文件。
  3. 主线程从工作线程接收消息后将运行使用音频元素的 WAV 文件。

在我看来,为了获得更好的性能,可以创建工作池。

请看演示here

我真的建议你看看 Philip Roberts 关于什么是 事件循环 以及为什么 setTimeout 0 有意义的精彩总结:https://www.youtube.com/watch?v=8aGhZQkoFbQ

简而言之,一个快速的解决方案可能就是 Booster2ooo 所说的,将调用包装在 setTimeout 调用中:

setTimeout(function() { window.speechSynthesis.speak(msg); }, 0);