我在使用 Google Chrome 语音合成时遇到这个问题已经有一段时间了。经过一番调查,我发现了以下几点:
- 言语的断裂仅当声音不是母语时才会发生,
- 切断通常发生在200-300 个字符,
- 当它确实损坏时,您可以通过执行以下操作来解冻它
speechSynthesis.cancel();
- The 'onend' 事件有时会决定不触发。一个奇怪的解决方法是在说出话语对象之前使用 console.log() 输出它。我还发现将发言调用包装在 setTimeout 回调中有助于解决这些问题。
为了解决这些问题,我编写了一个克服字符限制的函数,将文本分成更小的话语,然后一个接一个地播放它们。显然,有时你会听到一些奇怪的声音,因为句子可能会被分成两个单独的话语,每个话语之间有一个小的时间延迟,however代码将尝试在标点符号处分割这些点,以使声音的中断不那么明显。
Update
我已将此解决方法公开发布于https://gist.github.com/woollsta/2d146f13878a301b36d7#file-chunkify-js https://gist.github.com/woollsta/2d146f13878a301b36d7#file-chunkify-js。非常感谢布雷特·扎米尔 https://gist.github.com/brettz9感谢他的贡献。
功能:
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[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 - 1;
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);
};
如何使用它...
//create an utterance as you normally would...
var myLongText = "This is some long text, oh my goodness look how long I'm getting, wooooohooo!";
var utterance = new SpeechSynthesisUtterance(myLongText);
//modify it as you normally would
var voiceArr = speechSynthesis.getVoices();
utterance.voice = voiceArr[2];
//pass it into the chunking function to have it played out.
//you can set the max number of characters by changing the chunkLength property below.
//a callback function can also be added that will fire once the entire text has been spoken.
speechUtteranceChunker(utterance, {
chunkLength: 120
}, function () {
//some code to execute when done
console.log('done');
});
希望人们发现这很有用。