如何使用 Web Speech API 来听文本区域的每行单词,每行都有延迟?

How does one use the Web Speech API in a way that one can listen to the words of a textarea's lines, each line in a delayed way?

我正在尝试按行拆分文本区域,并使用文本到语音转换,以便每行都被朗读出来。 我想最终在每行之间添加 5 秒的延迟。

但是 for 循环没有按预期工作,我得到的是第一行的值,然后是最后一行中重复数组长度的值。

例如。 输入: 一种 乙 C D

输出: A, D, D, D

预计: A、B、C、D

  document.querySelector("#start").addEventListener("click", () => {
  // Set the text property with the value of the textarea
  textInput = document.getElementById("textarea");
  textArray = textInput.value.split(/\n/g);

  for (var i = 0; i<textArray.length; i++) {
    textInput = document.getElementById("textarea");
    textArray = textInput.value.split(/\n/g);

    speech.text = textArray[i]; 
    window.speechSynthesis.speak(speech);

  }

});

如果 OP 的 speech 对象是 SpeechSynthesisUtterance instance there is the possibility to listen to such an object's events like start and end

因此,已经解决了通过 for 循环将数组的文本行立即提供给 speech.text 的问题,这主要是导致 read/spoken 只是第一行并重复最后一行的结果值。

通过引入事件处理程序,还可以通过 setTimeout 延迟事件处理,正如 OP 所希望的那样。

并且为了创建一个 cycle/loop 的延迟语音台词,人们可能会考虑使用一个 generator created by a generator function 来产生仍然可用/尚未使用的语音台词。

function* createLinePool(value) {
  const listOfLines = String(value)
    .split(/\n/g)
    .map(line => line.trim())
    .filter(line => line !== '');

  let line;
  while (line = listOfLines.shift()) {

    yield line;
  }
}
function readTextAreaLineWise() {
  const recitation = new SpeechSynthesisUtterance();

  const textInput = document.querySelector('#textarea');
  const linePool = createLinePool(textInput.value);

  function readLine() {
    const nextLineItem = linePool.next();

    if (!nextLineItem.done) {
      console.log({ nextLineItem });

      recitation.text = nextLineItem.value;
      window.speechSynthesis.speak(recitation);
    }
  }
  recitation.addEventListener('end', () => {
    setTimeout(readLine, 2000);
  });
  
  // trigger first line getting read.
  readLine();
}

document
  .querySelector('#start')
  .addEventListener('click', readTextAreaLineWise);
* { margin: 0; }
.as-console-wrapper {
  min-height: 100%!important;
  width: 50%;
  left: auto!important;
  right: 0;
}
#textarea { width: 48%; }
#start { display: block }
<textarea id="textarea" cols="26" rows="9">
  
  Hallo world.
  
  
  The quick brown fox,
  
  jumps over the lazy dog.
</textarea>
<button id="start">Start</button>