中文文本使用Web Speech API播放一次,但第二次不播放

时间:2018-08-02 22:21:17

标签: javascript webspeech-api

因此,我正在使用经过修改的脚本来尝试播放Web Speech API中的某些文本。

代码最初在这里:

Chrome Speech Synthesis with longer texts

这是我的修改版本:

function googleSpeech(text, rate) {
    if (!reading) {
        speechSynthesis.cancel();
        if (timer) {
            clearInterval(timer);
        }
        let msg = new SpeechSynthesisUtterance();
        let voices = window.speechSynthesis.getVoices();
        msg.voice = voices[63];
        msg.voiceURI = 'native';
        msg.volume = 1; // 0 to 1
        msg.rate = rate; // 0.1 to 10
        msg.pitch = 1; //0 to 2
        msg.text = text;
        msg.lang = 'zh-CN';

        msg.onerror = function (e) {
            speechSynthesis.cancel();
            reading = false;
            clearInterval(timer);
        };

        msg.onpause = function (e) {
        };

        msg.onboundary = function (event) {
        };

        msg.onend = function (e) {
            speechSynthesis.cancel();
            reading = false;
            clearInterval(timer);
        };

        speechSynthesis.onerror = function (e) {
            speechSynthesis.cancel();
            reading = false;
            clearInterval(timer);
        };

        console.log(msg);
        speechSynthesis.speak(msg);

        timer = setInterval(function () {
            if (speechSynthesis.paused) {
                speechSynthesis.resume();
            }

        }, 100);

        reading = true;
    }

}

我能够一次玩这个游戏。每当我尝试再次播放它时,它都将不起作用-尽管运行了speechSynthesis.cancel();,但这仍然不起作用。当我重新加载页面时,一切再次正常运行-可以播放一次。

是否有任何一致的方式可以再次播放文字?似乎这可能与Web Speech API中的许多错误有关。这是在Chrome 68上。

以下是我正在播放的文字的示例:

我是一个兵。来自老百姓。 打败了日本狗强盗。 消灭了蒋匪军。

3 个答案:

答案 0 :(得分:4)

您的代码按原样工作,除了我必须在函数之前定义this->datareading = false

我的观察是,当您在不在 timer = false之间传递速率值时,您的函数仅被调用一次。您可能需要检查0.1 to 1o的值。

此外,如果费率值不在指定范围之间,则您的rate事件不会接到电话。

我的系统是onend,chrome是Mac

Version 67.0.3396.99 (Official Build) (64-bit)

答案 1 :(得分:1)

let reading = false;
let timer;
// let VV="ja-JP";
let VV = 'en-US';


function handleSaying(msg, text, rate) {
  let voices = window.speechSynthesis.getVoices();


  // console.log(voices);
  msg.voice = voices.filter(v => v.lang === VV)[0];

  // console.log("voice: ", msg.voice);
  msg.voiceURI = 'native';
  msg.volume = 1; // 0 to 1
  msg.rate = rate; // 0.1 to 10
  msg.pitch = 1; //0 to 2
  msg.text = text;
  msg.lang = VV;

  msg.onerror = function(e) {
    speechSynthesis.cancel();
    reading = false;
    clearInterval(timer);
  };

  msg.onpause = function(e) {};

  msg.onboundary = function(event) {};

  msg.onend = function(e) {
    console.log("On end...");
    // speechSynthesis.cancel();
    reading = false;
    clearInterval(timer);
  };

  speechSynthesis.onerror = function(e) {
    speechSynthesis.cancel();
    reading = false;
    clearInterval(timer);
  };

  speechSynthesis.speak(msg);

  timer = setInterval(function() {
    if (speechSynthesis.paused) {
      speechSynthesis.resume();
    }

  }, 100);

  reading = true;
}


function googleSpeech(text, rate) {

  if (!reading) {
    speechSynthesis.cancel();
    if (timer) {
      clearInterval(timer);
    }
    let msg = new SpeechSynthesisUtterance();

    // Here is the problem -- if the voices are ALREADY loaded from an earlier attempt
    // onvoiceschanged does not fire a second time

    if (window.speechSynthesis.getVoices().length > 0) {
      handleSaying(msg, text, rate);
    }


    // wait on voices to be loaded before fetching list
    window.speechSynthesis.onvoiceschanged = function() {
      handleSaying(msg, text, rate);
    }

  };

}
<button type="button" onclick="googleSpeech('The quick brown fox jumped over the lazy dogs', 5)">English</button>

我已经修改了您的代码以播放声音两次,并且在代码中评论了问题所在。我之前遇到过这个问题-这是一个难题。

我还遇到了onvoicechanged多次触发的问题,因为它先加载语音再加载更多。我没有输入代码来验证我们想要的声音是否存在。

我的系统无法播放您尝试使用的任何语言,因此我改用英语文字和语音,但这很容易改回来。

我还删除了对特定语音号码的硬编码参考,因为这些可以更改。相反,我会寻找与语言ID相匹配的第一个语音。

您可能要参考此答案。

Getting the list of voices in speechSynthesis of Chrome (Web Speech API)

答案 2 :(得分:1)

答案实际上与rate属性的值有关。

虽然Web Speech API的官方文档说它支持的速率值为.1到10,但看来Chrome(至少是我正在运行的版本Chrome 68)不完全支持速率。 .5到2的范围。

任何超出此范围的声音都会导致声音分散并在使用API​​后中断,并且直到刷新页面后声音才起作用。