Get spoken word with SpeechSynthesis

by Carlos Delgado

HTML

<textarea id="textarea" style="width:200px;height:200px;">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).</textarea><br>
<input type="button" id="playbtn" value="Click to speak text and show word in span !"/><br>
Speaking word : <span id="word" style="color:blue;"></span><br><br>
<div id="panel" style="min-width:300px;word-wrap:wrap;display:inline-block;">

</div>

JavaScript

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;
    }
}