SpeechSynthesis API onend обратный вызов не работает

я использую API синтеза речи на Google Chrome v34.0.1847.131. API реализован в Chrome, начиная с v33.

text-to-speech работает по большей части, за исключением случаев назначения обратного вызова 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.

7 ответов


хотя именно так я нашел его, чтобы заставить его работать, я не уверен, что это правильное поведение....

сначала не вызывайте функцию speak сразу, используйте обратный вызов.

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

демо:http://jsfiddle.net/QYw6b/2/

вы получите время прошло, и оба события произвели точно.


по данным комментарий об ошибке, упомянутой в ответ от Кевина Хакансона, это может быть проблемой со сбором мусора. Сохранение высказывания в переменной перед вызовом speak кажется, делает трюк:

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

вы можете использовать EventListener для начала и конца, как я сделал для Speakerbot (http://www.speakerbot.de/).

здесь мое лицо меняется во время произнесения слов.

newUtt = new SpeechSynthesisUtterance();

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

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

Я нашел оба решения, предложенные здесь, не работает в приложение, которое я только что написал. Единственное решение, которое я мог придумать, - это (своего рода) напряженное ожидание:

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

вы можете найти полный пример в это codepen


Это похоже на ошибку хрома, сообщенную 12 июля 2015 года.

вопрос 509488: Web Speech API: событие " end " объекта SpeechSynthesisUtterance иногда не отправляется


печать высказывания, прежде чем говорить, кажется, работает... Если я удалю консоль, эта проблема произойдет, не знаю, почему

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

Я нашел единственный способ сделать это надежно в использовании .Канс. Я использую 17 секундный тайм-аут. Все мои записи по 20 секунд, так что это работает для меня.

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

прежде чем я столкнусь с этой проблемой один раз каждые 8-10 сообщений, которые он пытался. Один раз я добавил :отмена, кажется, всегда работает. Я также вызываю set timeout при вызове.

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