使用 SpeechSynthesisUtterance API 时是否可以选择正在朗读的单词?

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

使用 SpeechSynthesisUtterance API 时是否可以选择正在朗读的单词?

是否有一个事件可以用来获取当前所说的单词和光标位置?

这是我到目前为止所拥有的:

var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();
msg.voice = voices[10]; // Note: some voices don't support altering params
msg.voiceURI = 'native';
msg.volume = 1; // 0 to 1
msg.rate = 1; // 0.1 to 10
msg.pitch = 2; //0 to 2
msg.text = 'Hello World';
msg.lang = 'en-US';

msg.onend = function(e) {
  console.log('Finished in ' + event.elapsedTime + ' seconds.');
};

speechSynthesis.speak(msg);

示例来自此处

text-to-speech speech-synthesis
3个回答
14
投票

有一个相关问题将单词写出了一个跨度,我在这里将答案扩展为选择说出的单词。

var utterance = new SpeechSynthesisUtterance();
utterance.lang = 'en-UK';
utterance.rate = 1;

document.getElementById('playButton').onclick = function(){
    var text = document.getElementById('textarea').value;
    // create the utterance on play in case user called stop
    // reference https://stackoverflow.com/a/47276578/441016
    utterance = new SpeechSynthesisUtterance();
    utterance.onboundary = onboundaryHandler;
    utterance.text = text;
    speechSynthesis.speak(utterance);
};

document.getElementById('pauseButton').onclick = function(){
    if (speechSynthesis) {
      speechSynthesis.pause();
    }
};

document.getElementById('resumeButton').onclick = function(){
    if (speechSynthesis) {
      speechSynthesis.resume();
    }
};

document.getElementById('stopButton').onclick = function(){
    if (speechSynthesis) {
      speechSynthesis.cancel();
    }
};

function onboundaryHandler(event){
    var textarea = document.getElementById('textarea');
    var value = textarea.value;
    var index = event.charIndex;
    var word = getWordAt(value, index);
    var anchorPosition = getWordStart(value, index);
    var activePosition = anchorPosition + word.length;
    
    textarea.focus();
    
    if (textarea.setSelectionRange) {
       textarea.setSelectionRange(anchorPosition, activePosition);
    }
    else {
       var range = textarea.createTextRange();
       range.collapse(true);
       range.moveEnd('character', activePosition);
       range.moveStart('character', anchorPosition);
       range.select();
    }
};

// Get the word of a string given the string and index
function getWordAt(str, pos) {
    // Perform type conversions.
    str = String(str);
    pos = Number(pos) >>> 0;

    // Search for the word's beginning and end.
    var left = str.slice(0, pos + 1).search(/\S+$/),
        right = str.slice(pos).search(/\s/);

    // The last word in the string is a special case.
    if (right < 0) {
        return str.slice(left);
    }
    
    // Return the word, using the located bounds to extract it from the string.
    return str.slice(left, right + pos);
}

// Get the position of the beginning of the word
function getWordStart(str, pos) {
    str = String(str);
    pos = Number(pos) >>> 0;

    // Search for the word's beginning
    var start = str.slice(0, pos + 1).search(/\S+$/);
    return start;
}
<textarea id="textarea" style="width:100%;height:150px;">
Science Literacy is a way of approaching the world. It's a way of equipping yourself to interpret what happens in front of you. It's methods and tools that enable it to act as a kind of a utility belt necessary for what you encounter in the moment. It's methods of mathematical analysis, interpretation, some basic laws of physics so when someone says I have these two crystals and if you rub them together you get healthy. Rather than just discount it, because that's as lazy as accepting it, what you should do is inquire. 

So do you know how to inquire? Every scientist would know how to start that conversation. Where did you get these? What does it cure? How does it work? How much does it cost? Can you demonstrate? Science literacy is vaccine against charlatans of the world that would exploit your ignorance of the forces of nature. Become scientifically literate.
</textarea><br>
<input type="button" id="playButton" value="Play"/>
<input type="button" id="pauseButton" value="Pause"/>
<input type="button" id="resumeButton" value="Resume"/>
<input type="button" id="stopButton" value="Stop"/>

MDN 语音合成
MDN 语音合成事件
MDN 边界


0
投票
//NOTE: A USER MUST INTERACT WITH THE BROWSER before sound will play.
const msg = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
msg.voice = voices[10]; // Note: some voices don't support altering params
msg.voiceURI = 'native';
msg.volume = 1; // 0 to 1
msg.rate = 1; // 0.1 to 10
msg.pitch = 2; //0 to 2
txt = "I'm fine, borderline, so bad it hurts Think fast with your money cause it can't get much worse I get told that I'm far too old for number one perks".split(" ")
msg.text = txt;
msg.lang = 'en-US';

msg.onend = function(e) {
  console.log('Finished in ' + event.elapsedTime + ' seconds.');
};

let gap = 240
let i = 0
speakTrack = setInterval(() => {
  console.log(txt[i++])
  //i++ < dont forget if you remove console log
  if (i >= txt.length) {
    i = 0
    clearInterval(speakTrack)
  }
}, gap)

speechSynthesis.speak(msg);

https://jsfiddle.net/Vinnywoo/bvt314sa


0
投票

我添加了 4 行(来自这个答案),为上面的 1.21 吉瓦答案添加滚动功能。

        var utterance = new SpeechSynthesisUtterance();
            utterance.lang = 'en-UK';
            utterance.rate = 1;

            document.getElementById('playButton').onclick = function(){
            var text = document.getElementById('textarea').value;
            // create the utterance on play in case user called stop
            // reference https://stackoverflow.com/a/47276578/441016
            utterance = new SpeechSynthesisUtterance();
            utterance.onboundary = onboundaryHandler;
            utterance.text = text;
            speechSynthesis.speak(utterance);
            };

            document.getElementById('pauseButton').onclick = function(){
            if (speechSynthesis) {
              speechSynthesis.pause();
            }
            };

            document.getElementById('resumeButton').onclick = function(){
            if (speechSynthesis) {
              speechSynthesis.resume();
            }
        };

            document.getElementById('stopButton').onclick = function(){
            if (speechSynthesis) {
              speechSynthesis.cancel();
            }
        };

            function onboundaryHandler(event){
            var textarea = document.getElementById('textarea');
            var value = textarea.value;
            var index = event.charIndex;
            var word = getWordAt(value, index);
            var anchorPosition = getWordStart(value, index);
            var activePosition = anchorPosition + word.length;
            
            textarea.focus();
            // Added lines to scroll
            const fullText = textarea.value;
            textarea.value = fullText.substring(0, activePosition);
            textarea.scrollTop = textarea.scrollHeight;
            textarea.value = fullText;   
            // end added lines to scroll
            if (textarea.setSelectionRange) {
               textarea.setSelectionRange(anchorPosition, activePosition);
            }
            else {
               var range = textarea.createTextRange();
               range.collapse(true);
               range.moveEnd('character', activePosition);
               range.moveStart('character', anchorPosition);
               range.select();
            }
        };

            // Get the word of a string given the string and index
            function getWordAt(str, pos) {
            // Perform type conversions.
            str = String(str);
            pos = Number(pos) >>> 0;

            // Search for the word's beginning and end.
            var left = str.slice(0, pos + 1).search(/\S+$/),
                right = str.slice(pos).search(/\s/);

            // The last word in the string is a special case.
            if (right < 0) {
                return str.slice(left);
            }
            
            // Return the word, using the located bounds to extract it from the string.
            return str.slice(left, right + pos);
        }

            // Get the position of the beginning of the word
            function getWordStart(str, pos) {
            str = String(str);
            pos = Number(pos) >>> 0;

            // Search for the word's beginning
            var start = str.slice(0, pos + 1).search(/\S+$/);
            return start;
        }
  
            <textarea id="textarea" style="width:100%;height:150px;">
            Science Literacy is a way of approaching the world. It's a way of equipping                 yourself to interpret what happens in front of you. It's methods and tools that enable it to act as a kind of a utility belt necessary for what you encounter in the moment. It's methods of mathematical analysis, interpretation, some basic laws of physics so when someone says I have these two crystals and if you rub them together you get healthy. Rather than just discount it, because that's as lazy as accepting it, what you should do is inquire. 

        So do you know how to inquire? Every scientist would know how to start that conversation. Where did you get these? What does it cure? How does it work? How much does it cost? Can you demonstrate? Science literacy is vaccine against charlatans of the world that would exploit your ignorance of the forces of nature. Become scientifically literate.
        </textarea><br>
        <input type="button" id="playButton" value="Play"/>
        <input type="button" id="pauseButton" value="Pause"/>
        <input type="button" id="resumeButton" value="Resume"/>
        <input type="button" id="stopButton" value="Stop"/>

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