SpeechSynthesis API一次回调无法正常工作

时间:2014-05-06 00:17:28

标签: javascript google-chrome text-to-speech speech-synthesis google-text-to-speech

我在Google Chrome v34.0.1847.131上使用Speech Synthesis API。该API在v33中开始在Chrome中实现。

除了将回调分配给onend之外,文本转语音大部分都有效。例如,以下代码:

var message = window.SpeechSynthesisUtterance("Hello world!");
message.onend = function(event) {
    console.log('Finished in ' + event.elapsedTime + ' seconds.');
};
window.speechSynthesis.speak(message);

有时会调用onend,有时不会调用它。时机似乎完全没有了。当它被调用时,打印的elapsedTime总是像1399237888一样的纪元时间。

9 个答案:

答案 0 :(得分:20)

根据this comment关于Kevin Hakanson的the answer中提到的错误,它可能是垃圾收集的问题。在调用speak seems to do the trick之前将话语存储在变量中:

window.utterances = [];
var utterance = new SpeechSynthesisUtterance( 'hello' );
utterances.push( utterance );
speechSynthesis.speak( utterance );

答案 1 :(得分:9)

虽然这是我发现它的工作方式,但我不确定这是否是正确的行为....

首先不要立即调用说话功能,使用回调。

第二,有时间使用timeStamp代替elapsedTime。您也可以使用performance.now()

var btn = document.getElementById('btn');
speechSynthesis.cancel()
var u = new SpeechSynthesisUtterance();
u.text = "This text was changed from the original demo.";

var t;
u.onstart = function (event) {
    t = event.timeStamp;
    console.log(t);
};

u.onend = function (event) {
    t = event.timeStamp - t;
    console.log(event.timeStamp);
    console.log((t / 1000) + " seconds");
};

btn.onclick = function () {speechSynthesis.speak(u);};

演示:http://jsfiddle.net/QYw6b/2/

你得到时间,两个事件肯定都被解雇了。

答案 2 :(得分:4)

您可以像使用Speakerbot( http://www.speakerbot.de/ )一样使用EventListener进行开始和结束。

在说话的时候,我的脸变了。

newUtt = new SpeechSynthesisUtterance();

newUtt.addEventListener('start', function () {
     console.log('started');
})

newUtt.addEventListener('end', function () {
     console.log('stopped');
})

答案 3 :(得分:3)

我发现这里建议的两个解决方案都不适用于an app I just wrote。我能想到的唯一解决方案是(等待)忙碌的等待:

function speak( text, onend ) {
  window.speechSynthesis.cancel();
  var ssu = new SpeechSynthesisUtterance( text );
  window.speechSynthesis.speak( ssu );
  function _wait() {
    if ( ! window.speechSynthesis.speaking ) {
      onend();
      return;
    }
    window.setTimeout( _wait, 200 );
  }
  _wait();
}

您可以在this codepen

中找到完整的示例

答案 4 :(得分:3)

这看起来类似于2015年7月12日报道的Chromium bug。

  

问题509488:网络语音API:'结束'有时没有调度SpeechSynthesisUtterance对象的事件

答案 5 :(得分:1)

在说话之前打印话语似乎正在工作...... 如果我删除控制台,这个问题就会发生,不知道为什么

console.log("utterance", utterThis);
synth.speak(utterThis);

答案 6 :(得分:0)

我还发现使这项工作可靠的唯一方法是使用.cance。我使用17秒超时。我的所有录音都不到20秒,所以这对我有用。

utterance.onstart = function (event) {
setTimeout(function(){window.speechSynthesis.cancel();},17000);
};

在我尝试每8-10条消息之前遇到此问题之前。一旦我添加.cancel它似乎总是有效。我也在调用时调用set timeout。

setTimeout(function(){window.speechSynthesis.speak(utterance);},100);

答案 7 :(得分:0)

唯一对我有用的是避免出现 localServicetrue 的声音。这些语音从未触发 onend,而其他语音(localService 为假)确实触发了 onend

答案 8 :(得分:0)

此外,在 Chrome(但不是 Safari)上,如果您尝试说出空字符串,则永远不会调用回调。