【问题标题】:Speech Synthesis API Highlight words as they are spoken语音合成 API 在说出单词时突出显示它们
【发布时间】:2016-06-30 10:28:37
【问题描述】:

目前,我正在制作一个使用语音合成 API 朗读文本的简单应用。我想在说话时突出显示单词(粗体)。我目前有一个非常基本的实现,使用 'onboundary' 事件。但是,我想知道是否有更好/更好的方法,因为我的实现是基于一些假设。

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

window.onload = function(){
    document.getElementById('textarea').innerText = 'This is a text area.  It is used as a simple test to check whether these words are highlighted as they are spoken using the web speech synthesis API (utterance).';

    document.getElementById('playbtn').onclick = function(){
        text    = document.getElementById('textarea').innerText;
        words   = text.split(' ');
        wordIdx = 0;

        utterance.text = text;
        speechSynthesis.speak(utterance);
    }

    utterance.onboundary = function(event){
        var e = document.getElementById('textarea');
        var it = '';

        for(var i = 0; i < words.length; i++){
            if(i === wordIdx){
                it += '<strong>' + words[i] + '</strong>';
            } else {
                it += words[i];
            }

            it += ' ';
        }

        e.innerHTML = it;
        wordIdx++;
    }
}

【问题讨论】:

    标签: javascript html speech-synthesis


    【解决方案1】:

    您的代码不起作用,但我只是编写了一个可以按照您想要的方式工作的示例。打开小提琴看看它的工作原理

    var utterance = new SpeechSynthesisUtterance();
    var wordIndex = 0;
    var global_words = [];
    utterance.lang = 'en-UK';
    utterance.rate = 1;
    
    
    document.getElementById('playbtn').onclick = function(){
        var text    = document.getElementById('textarea').value;
        var words   = text.split(" ");
        global_words = words;
        // Draw the text in a div
        drawTextInPanel(words);
        spokenTextArray = words;
        utterance.text = text;
        speechSynthesis.speak(utterance);
    };
    
    utterance.onboundary = function(event){
        var e = document.getElementById('textarea');
        var word = getWordAt(e.value,event.charIndex);
        // Show Speaking word : x
        document.getElementById("word").innerHTML = word;
        //Increase index of span to highlight
        console.info(global_words[wordIndex]);
    
        try{
            document.getElementById("word_span_"+wordIndex).style.color = "blue";
        }catch(e){}
    
        wordIndex++;
    };
    
    utterance.onend = function(){
            document.getElementById("word").innerHTML = "";
        wordIndex = 0;
        document.getElementById("panel").innerHTML = "";
    };
    
    // Get the word of a string given the string and the 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);
    }
    
    function drawTextInPanel(words_array){
    console.log("Dibujado");
            var panel = document.getElementById("panel");
        for(var i = 0;i < words_array.length;i++){
            var html = '<span id="word_span_'+i+'">'+words_array[i]+'</span>&nbsp;';
            panel.innerHTML += html;
        }
    }
    

    请弹奏以下小提琴:

    Highlight spoken word SpeechSynthesis Javascript fiddle

    它用蓝色突出显示div中的口语,您可以自定义它的粗体样式,但重要的是想法。

    注意:请记住,onboundary 事件仅针对本机(本地)语音合成触发。更改 Google 示例中指定的语音(即 Google UK English Male)为 google 远程语音,将使您的代码失败,因为 SpeechSynthesis API 似乎只播放由 google 服务器生成的声音。

    【讨论】:

    • 您是否有关于边界事件的注释的参考,或者这只是您注意到的东西?我遇到了同样的事情,并试图找出这是否应该得到支持。
    • 这是您答案的略微修改版本,它选择了文本区域 stackoverflow.com/a/50285928/441016 内的单词。
    猜你喜欢
    • 2017-09-08
    • 1970-01-01
    • 2013-09-15
    • 2014-08-07
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多