web-dev-qa-db-fra.com

L'appel à la fin de l'API SpeechSynthesis ne fonctionne pas

J'utilise l'API Speech Synthesis sur Google Chrome v34.0.1847.131. L'API est implémentée dans Chrome à partir de v33.

La synthèse vocale fonctionne pour la plupart, sauf lorsque vous affectez un rappel à onend. Par exemple, le code suivant:

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

appellera parfois onend et parfois pas. Le timing semble être complètement éteint. Lorsqu'il est appelé, la elapsedTime imprimée correspond toujours à une époque telle que 1399237888.

25
huu

Bien que ce soit ce qui m'a permis de le faire fonctionner, je ne suis pas sûr que ce soit le bon comportement ...

D'abord, n'appelez pas la fonction de conversation tout de suite, utilisez le rappel.

Deuxièmement, pour obtenir le temps, utilisez timeStamp au lieu de elapsedTime. Vous auriez pu simplement utiliser performance.now() également. 

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

Démo: http://jsfiddle.net/QYw6b/2/

vous avez le temps passé et les deux événements déclenchés à coup sûr. 

9
Muhammad Umer

Selon ce commentaire sur le bogue mentionné dans la réponse de Kevin Hakanson, il pourrait s'agir d'un problème de récupération de place. Stocker l'énoncé dans une variable avant d'appeler speaksemble faire l'affaire :

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

Vous pouvez utiliser EventListener pour démarrer et terminer comme je l’ai fait pour Speakerbot (http://www.speakerbot.de/). 

Ici, mon visage change tandis que les mots sont prononcés.

newUtt = new SpeechSynthesisUtterance();

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

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

J'ai trouvé les deux solutions suggérées ici ne fonctionnant pas dans une application que je viens d'écrire . La seule solution que je pourrais trouver est une attente (en quelque sorte) occupée: 

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

vous pouvez trouver un exemple complet dans this codepen

3
Mapio

Cela ressemble à un bug de chrome signalé le 12 juillet 2015.

Numéro 509488 : API Web Speech: l'événement 'end' de l'objet SpeechSynthesisUtterance n'est pas parfois distribué

3
Kevin Hakanson

imprimer l'énoncé avant de parler semble fonctionner ....... Si je supprime la console, ce problème se produira, je ne sais pas pourquoi

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

J'ai également trouvé que la seule façon de rendre ce travail fiable est d'utiliser .cance. J'utilise un délai d'attente de 17 secondes. Tous mes enregistrements durent moins de 20 secondes, donc cela fonctionne pour moi.

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

Avant, je rencontrais ce problème une fois tous les 8-10 messages essayés. Une fois que j’ai ajouté .cancel, cela semble toujours fonctionner. J'appelle aussi set timeout lors de l'appel.

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