我目前正在开发一个 Web 项目,使用 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);
});
}
您可以通过侦听 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>