javascript SpeechSynthesis API onend 回调不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23483990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 00:58:26  来源:igfitidea点击:

SpeechSynthesis API onend callback not working

javascriptgoogle-chrometext-to-speechspeech-synthesisgoogle-text-to-speech

提问by huu

I'm using the Speech Synthesis APIon Google Chrome v34.0.1847.131. The API is implemented in Chrome starting in v33.

我在 Google Chrome v34.0.1847.131 上使用语音合成 API。从 v33 开始,该 API 在 Chrome 中实现。

The text-to-speech works for the most part, except when assigning a callback to onend. For instance, the following code:

文本转语音在大多数情况下都有效,除非将回调分配给onend。例如,以下代码:

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

will sometimes call onendand sometimes not call it. The timing appears to be completely off. When it does get called, the printed elapsedTimeis always some epoch time like 1399237888.

有时会调用onend有时不调用。时间似乎完全关闭。当它被调用时,打印出来elapsedTime的总是像1399237888.

采纳答案by Muhammad Umer

While this is how I found it to make it work, I am not sure if this is the right behavior....

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

First don't call the speak function it right away, use callback.

首先不要马上调用speak函数,使用回调。

2nd, to get time use timeStampinstead of elapsedTime. You could have just used performance.now()as well.

2,获得时间使用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);};

Demo: http://jsfiddle.net/QYw6b/2/

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

you get time passed and both events fired for sure.

时间过去了,这两个事件肯定会被触发。

回答by techpeace

According to this commenton the bug mentioned in the answerfrom Kevin Hakanson, it might be a problem with garbage collection. Storing the utterance in a variable before calling speakseems to do the trick:

根据对Kevin Hakanson的回答中提到的错误的评论,这可能是垃圾收集的问题。在调用之前将话语存储在变量中似乎可以解决问题speak

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

回答by fimbim

You could use the EventListener for start and end like I did for Speakerbot (http://www.speakerbot.de/).

您可以像我为 Speakerbot ( http://www.speakerbot.de/)所做的那样使用 EventListener 开始和结束。

Here my face changes while words are spoken.

在这里,说话时我的脸色会发生变化。

newUtt = new SpeechSynthesisUtterance();

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

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

回答by Mapio

I found both solutions suggested here not working in an app I just wrote. The only solution I could come up with is a (sort of) busy waiting:

我发现这里建议的两种解决方案都不适用于我刚刚编写的应用程序。我能想出的唯一解决方案是(有点)忙着等待:

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();
}

you can find a complete example in this codepen

你可以在这个代码笔中找到一个完整的例子

回答by Kevin Hakanson

This looks similar to a Chromium bug reported on Jul 12, 2015.

这看起来类似于 2015 年 7 月 12 日报告的 Chromium 错误。

Issue 509488: Web Speech API: 'end' event of SpeechSynthesisUtterance object is not dispatched sometimes

问题509488:Web Speech API:有时不会调度 SpeechSynthesisUtterance 对象的“结束”事件

回答by yun

print the utterance before speak seems working... If I remove the console, this issue will happen, don't know why

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

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

回答by Bruce Allen

I also found the only way to make this work reliably is to use .cance. I use a 17 second timeout. All of my recordings are under 20 seconds so this works for me.

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

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

Before I would run into this problem once every 8-10 messages it attempted. Once I added .cancel it seems to always work. I also call set timeout when invoking.

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

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