SpeechSynthesis.speaking永远不会成真

时间:2017-10-03 19:07:39

标签: javascript text-to-speech

我尝试用javascript实现一个小网页,允许从两个mp3之间的文本中播放一个spechsynthesis部分。

无论出于何种原因,口头部分的一个陈述不起作用,我想创建一个递归函数,这对我有帮助。为此,我使用SpeechSynthesis的“说话”方法。但无论出于何种原因,说话永远不会成真。

我已经调试并尝试了几个语句(参见代码),但它从未证明是真的。代码中有什么东西吗?否则,如何报告此库的错误?

        function doSpeech() {
            var synth = window.speechSynthesis;

            var utterance1 = new SpeechSynthesisUtterance('How about we say this now? This is quite a long sentence to say.');
            var utterance2 = new SpeechSynthesisUtterance('We should say another sentence too, just to be on the safe side.');
            synth.speak(utterance1);
            if(synth.speaking){
                doNothing();
            }else{
                playEnd();
            }
如果synth说话的话,playEnd()只播放一个mp3。 请注意,当我在if语句中放入playEnd()时,它将无法播放。我可以把任何代码放在那里,它永远不会到达,因为synth.speaking永远不会是真的。此示例接近Mozilla基础文档的示例(https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis/speaking)。我想测试它,因为递归从未起作用。

编辑:递归仍然不会在我的特定编码中执行。我在这里错过了什么吗?

  function doSpeech() {
            var synth = window.speechSynthesis;
            var speech = new SpeechSynthesisUtterance();
            speech.text = getText();
            speech.lang = "en-US";
            speech.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == 'Google UK English Male'; })[0];

            speech.addEventListener('start', function(){
                speechEndLoop(synth);
            });


            synth.speak(speech);
    }

   function speechEndLoop(x) {
          if (x.speaking) {
               speechEndLoop(x);  
            } else {
               playEnd(); 
            }
        }

1 个答案:

答案 0 :(得分:1)

它运作正常,问题是根据您的代码,您将立即验证状态。这可能是一个问题,因为它取决于API如何将文本转换为音频(使用操作系统的本地文本语音或使用谷歌服务器):

function doSpeech() {
    var synth = window.speechSynthesis;

    var utterance1 = new SpeechSynthesisUtterance('How about we say this now? This is quite a long sentence to say. Make it longer !');
    var utterance2 = new SpeechSynthesisUtterance('We should say another sentence too, just to be on the safe side. even longer !');

    synth.speak(utterance1);

    // If you check immediately (js code executed in less than ms) the
    // status won't be true
    if (synth.speaking) {
        console.log("This is usually printed, if the utterance uses the default voice of the browser (native)");
    }

    // Wait 500ms to check for the status of the utterance
    setTimeout(function(){
        if (synth.speaking) {
            console.log("This will be printed if starts after 500ms :)");
        }
    }, 500);
}

doSpeech();

就我而言,正在打印两个console.log语句。但是,如果在您的情况下没有打印,请仅在话语的开始事件之后执行您的代码:

function doSpeech() {
    var synth = window.speechSynthesis;
    var msg = new SpeechSynthesisUtterance();
    msg.text = "We should say another sentence too, just to be on the safe side. even longer !";

    msg.addEventListener('start', function () {
        if(synth.speaking){
            console.log("This will be printed !");
        }
    });

    synth.speak(msg);
} 

doSpeech();

很高兴自己使用普通的API,但如果你想要更强大的东西来解决文本到语音问题,我建议你use the JS Library Artyom.js,它为语音合成提供了一个非常好的包装器API。即使使用此库,您也会看到相同的行为:

function doSpeech() {
    let assistant = new Artyom();

    assistant.say('How about we say this now? This is quite a long sentence to say. Make it longer !', {
        onStart: function() {
            if(assistant.isSpeaking()){
                console.log("This will be shown");
            }
        }
    });

    if(assistant.isSpeaking()){
        console.log("This won't appear !");
    }
} 

doSpeech();