如何在Web项目中同步SpeechSynthesis和文本颜色变化

问题描述 投票:0回答:1

我目前正在开发一个 Web 项目,使用 SpeechSynthesis API 来读取网页上的文本段落。我一直在尝试将口语与文本中的颜色变化同步,但我面临一些挑战。

以下是该问题的简要概述:

  • 我有一个函数,可以使用 SpeechSynthesis API 读取页面上

    标签的内容。

  • 目标是将口语与颜色变化实时同步。
  • 具体来说,我希望每个单词在说出时都变为红色,并在单词完成时恢复为原始颜色。
  • 每一次尝试都导致整个段落都变成红色。

我的没有同步的工作代码如下。

function speakAllParagraphs(page) {
  // Get all <p> elements within the current page
  var paragraphs = document
    .getElementById("page" + page)
    .getElementsByTagName("p");

  // Iterate through each <p> tag
  Array.from(paragraphs).forEach(function (paragraph, index) {
    // Speak the text of the paragraph
    var text = paragraph.innerText;

    // Create a new SpeechSynthesisUtterance
    var utterance = new SpeechSynthesisUtterance();
    utterance.text = text;

    // Find the voice by name
    const voices = speechSynthesis.getVoices();
    const targetVoice = voices.find(
      (voice) =>
        voice.name === "Microsoft Emily Online (Natural) - English (Ireland)"
    );

    if (targetVoice) {
      utterance.voice = targetVoice;
    } else {
      // Fallback: if the target voice is not available, use default voice
      utterance.voice = voices[0];
    }

    // Play the synthesized speech
    speechSynthesis.speak(utterance);
  });
}
  • 我尝试使用边界事件来更改单个单词的颜色,但它没有按预期工作。
  • 我尝试了几种方法,包括使用计时器和事件,但未能实现所需的同步。
  • 每一次尝试都导致整个段落都变成红色。
  • 目标是让每个单词在说出时变为红色,并在单词完成后恢复为原始颜色。
javascript html synchronization speech-synthesis webspeech-api
1个回答
0
投票

您可以通过侦听 boundary

 实例上的 
SpeechSynthesisUtterance
 事件来完成所需的行为。此事件将为您提供 
charIndex
charLength
属性,该属性将指示该特定时刻话语在字符串中的位置。

这允许您从字符串中抓取特定部分并将其包装在 HTML 中 - 就像下面示例中的

<mark>
标签一样 - 以突出显示当前的语音文本。替换段落文本以突出显示文本。

还监听

end
事件,以在话语结束时恢复段落中的原始文本。

const target = document.querySelector('p');

function speakAndHighlight(target) {
  const text = target.textContent;
  const utterance = new SpeechSynthesisUtterance();
  utterance.text = text;
  
  utterance.addEventListener('boundary', ({ charIndex, charLength }) => {    
    const beforeWord = text.slice(0, charIndex);
    const word = text.slice(charIndex, charIndex + charLength);
    const afterWord = text.slice(charIndex + charLength, text.length);
    
    target.innerHTML = `${beforeWord}<mark>${word}</mark>${afterWord}`
  });
  
  utterance.addEventListener('end', event => {
    target.textContent = text;
  });
  
  speechSynthesis.speak(utterance);
}

speakAndHighlight(target);
<p>"Sunsets paint the sky with hues of warmth, a daily masterpiece. Nature's farewell kiss, fleeting yet timeless, whispers serenity to all."</p>

© www.soinside.com 2019 - 2024. All rights reserved.