Skip to content

Instantly share code, notes, and snippets.

@hsed
Forked from woollsta/chunkify.js
Created March 18, 2017 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hsed/ef4a2d17f76983588cb6d2a11d4566d6 to your computer and use it in GitHub Desktop.
Save hsed/ef4a2d17f76983588cb6d2a11d4566d6 to your computer and use it in GitHub Desktop.
Fixes an issue with Google Chrome Speech Synthesis where long texts pause mid-speaking. The function takes in a speechUtterance object and intelligently chunks it into smaller blocks of text that are stringed together one after the other. Basically, you can play any length of text. See http://stackoverflow.com/questions/21947730/chrome-speech-sy…
/**
* Chunkify
* Google Chrome Speech Synthesis Chunking Pattern
* Fixes inconsistencies with speaking long texts in speechUtterance objects
* Licensed under the MIT License
*
* Peter Woolley and Brett Zamir
* Modified by Haaris for bug fixes
*/
var speechUtteranceChunker = function (utt, settings, callback) {
settings = settings || {};
var newUtt;
var txt = (settings && settings.offset !== undefined ? utt.text.substring(settings.offset) : utt.text);
if (utt.voice && utt.voice.voiceURI === 'native') { // Not part of the spec
newUtt = utt;
newUtt.text = txt;
newUtt.addEventListener('end', function () {
if (speechUtteranceChunker.cancel) {
speechUtteranceChunker.cancel = false;
}
if (callback !== undefined) {
callback();
}
});
}
else {
var chunkLength = (settings && settings.chunkLength) || 160;
var pattRegex = new RegExp('^[\\s\\S]{' + Math.floor(chunkLength / 2) + ',' + chunkLength + '}[.!?,]{1}|^[\\s\\S]{1,' + chunkLength + '}$|^[\\s\\S]{1,' + chunkLength + '} ');
var chunkArr = txt.match(pattRegex);
if (chunkArr == null || chunkArr[0] === undefined || chunkArr[0].length <= 2) {
//call once all text has been spoken...
if (callback !== undefined) {
callback();
}
return;
}
var chunk = chunkArr[0];
newUtt = new SpeechSynthesisUtterance(chunk);
var x;
for (x in utt) {
if (utt.hasOwnProperty(x) && x !== 'text') {
newUtt[x] = utt[x];
}
}
newUtt.addEventListener('end', function () {
if (speechUtteranceChunker.cancel) {
speechUtteranceChunker.cancel = false;
return;
}
settings.offset = settings.offset || 0;
settings.offset += chunk.length;
speechUtteranceChunker(utt, settings, callback);
});
}
if (settings.modifier) {
settings.modifier(newUtt);
}
console.log(newUtt); //IMPORTANT!! Do not remove: Logging the object out fixes some onend firing issues.
//placing the speak invocation inside a callback fixes ordering and onend issues.
setTimeout(function () {
speechSynthesis.speak(newUtt);
}, 0);
};
@sharjeelfaiq
Copy link

Hello author! I'm putting an argument based on my fresh experience with speechSynthesis. I'm trying to understand your code but most of the things are not giving sense to me. I want to use this code to make my following code speak the given text up to the end. Can you guide me on how to do this?

const read = () => {
            const textArea = document.getElementById("textarea");
            const btn = document.getElementById("btn");
            const input = textArea.value;
            const msg = new SpeechSynthesisUtterance(input);
            window.speechSynthesis.speak(msg);
        }
const cancel = () => {
            window.speechSynthesis.cancel();
        }

THANKS IN ADVANCE!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment