如何在带有语法提示的语音合成中插入停顿

How to insert pause in speech synthesis with grammatical hints

我正在使用 HTML5 SpeechSynthesis API 编写一个简单的拼写测试应用程序。我希望我的应用程序显示的文本类似于以下内容:"The spelling word is Cat. The cat chased the dog."。

API 倾向于从第一句到第二句不间断地进行比赛。我想知道是否有办法在两个句子之间插入一点停顿。我意识到我可以创建 2 个单独的话语并使用 pause() 调用。但是,如果我可以简单地插入语法提示,代码会更简单、更不脆弱。

通常在英语口语中,人们倾向于在段落之间停顿更长的时间。所以我在我的文本中插入了一个换行符,但没有明显的影响。

我也试过使用省略号。

有什么方法可以做到这一点,还是我坚持将所有内容分解成单独的话语?

只需插入

<silence msec="5000" />

在文本中等待 5 秒 (Source)。

免责声明:此代码仅适用于适当的用户代理。

// code taken from https://richjenks.com/dev/speechsynthesis/
var utterance  = new SpeechSynthesisUtterance(),
    speak      = document.getElementById("speak"),
    text       = document.getElementById("text");

// Delay links and events because speechSynthesis is funny
speechSynthesis.getVoices();
setTimeout(function () {
    // Add event listeners
    var voiceLinks = document.querySelectorAll(".voice");
    for (var i = 0; i < voiceLinks.length; i++) {
        voiceLinks[i].addEventListener("click", function (event) {
            utterance.voice = speechSynthesis.getVoices()[this.dataset.voice];
        });
    }
}, 100);

// Say text when button is clicked
speak.addEventListener("click", function (event) {
    utterance.text = text.value;
    speechSynthesis.speak(utterance);
});
<textarea id="text" rows="5" cols="50">Hi <silence msec="2000" /> Flash!</textarea>
<br>
<button id="speak">Speak</button>

我发现使用逗号插入合成停顿非常有用(作为进行其他操作)。以下是一小段摘录:

var speech = new SpeechSynthesisUtterance(),
    $content = document.querySelector('main').cloneNode(true),
    $space = $content.querySelectorAll('pre'),
    $pause_before = $content.querySelectorAll('h2, h3, h4, h5, h6, p, li, dt, blockquote, pre, figure, footer'),
    $skip = $content.querySelectorAll('aside, .dont_read');

// Don’t read
$skip.forEach(function( $el ){
    $el.innerHTML = '';
});

// spacing out content
$space.forEach(function($el){
    $el.innerHTML = ' ' + $el.innerHTML.replace(/[\r\n\t]/g, ' ') + ' ';
});

// Synthetic Pauses
$pause_before.forEach(function( $el ){
    $el.innerHTML = ' , ' + $el.innerHTML;
});

speech.text = $content.textContent;

关键是首先克隆内容节点,这样您就可以在内存中使用它,而不是操纵实际内容。它对我来说似乎工作得很好,我可以在 JavaScript 代码中控制它,而不必修改页面源代码。

使用感叹号“!”由于某种原因增加了一个很好的延迟。

您可以将它们与句点链接在一起以延长暂停时间。

"Example text! . ! . ! . !"

使用逗号(或自定义分隔符)拆分您的文本,并使用超时添加您自己的 space。

这里有一个简单的例子作为概念验证。扩展它,您可以自定义文本以包含有关暂停多长时间的提示。

function speakMessage(message, PAUSE_MS = 500) {
  try {
    const messageParts = message.split(',')

    let currentIndex = 0
    const speak = (textToSpeak) => {
      const msg = new SpeechSynthesisUtterance();
      const voices = window.speechSynthesis.getVoices();
      msg.voice = voices[0];
      msg.volume = 1; // 0 to 1
      msg.rate = 1; // 0.1 to 10
      msg.pitch = .1; // 0 to 2
      msg.text = textToSpeak;
      msg.lang = 'en-US';

      msg.onend = function() {
        currentIndex++;
        if (currentIndex < messageParts.length) {
          setTimeout(() => {
            speak(messageParts[currentIndex])
          }, PAUSE_MS)
        }
      };
      speechSynthesis.speak(msg);
    }
    speak(messageParts[0])
  } catch (e) {
    console.error(e)
  }
}


function run(pause) {
  speakMessage('Testing 1,2,3', pause)
}
<button onclick='run(0)'>Speak No Pause</button>
<button onclick='run(500)'>Speak Pause</button>
<button onclick='run(1000)'>Speak Pause Longer</button>