Я написал код для озвучивания текста текущей страницы.
Вот мой код:
$('#speak').on('click', function () {
if(!('speechSynthesis' in window)){
alert('This browser doesn\'t support this feature.\n Try again with Chrome browser');
return;
}
navigator.browserInfo= (function(){
var ua= navigator.userAgent, tem,
iOS = !!ua.match(/ip(ad|od|hone)/i),
webkit = !!ua.match(/Webkit/i),
iOSChrome = iOS && webkit && !ua.match(/Version/i) && ua.match(/CriOS/i) && !ua.match(/EdgeOS/i) && !ua.match(/OPiOS/i),
M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if(iOSChrome){
return {'browser': 'Chrome'};
}
if(/trident/i.test(M[1])){
tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
return 'IE '+(tem[1] || '');
}
if(M[1]=== 'Chrome'){
tem= ua.match(/\b(OPR|Edge?)\/(\d+)/);
if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera').replace('Edg ', 'Edge ');
}
M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
return {'browser': M[0], 'version': M[1]};
})();
if(navigator.browserInfo.browser != 'Chrome'){
alert('Try again with Chrome browser.');
return;
}
if ($(this).attr('data-opt') == 'cancel') {
timer(1);
window.speechSynthesis.cancel();
$(this).attr('data-opt', 'speak');
return;
}
var text = '';
if(currentPage == 1)
text = '';
else
text = currentPage >= 35? $('.page' + (currentPage + 1))[0].innerText : $('.page' + currentPage)[0].innerText;
if (text.trim() == null || text.trim() == '') {
text = 'There is no text to speak.';
}
speak(text);
});
function timer(end) {
if (end != null) {
clearTimeout(myTimeout);
return;
}
window.speechSynthesis.pause();
window.speechSynthesis.resume();
myTimeout = setTimeout(timer, 10000);
}
function speak(text) {
if (window.speechSynthesis.speaking) {
console.error('speechSynthesis.speaking');
return;
}
window.speechSynthesis.cancel();
if(navigator.userAgent.search('Android') == -1)
myTimeout = setTimeout(timer, 10000);
var msg = new SpeechSynthesisUtterance(text);
msg.pitch = 1;
msg.rate = 1;
for (var i = 0; i < window.speechSynthesis.getVoices().length; i++) {
if (window.speechSynthesis.getVoices()[i].lang == 'ko-KR') {
msg.voice = window.speechSynthesis.getVoices()[i];
break;
}
}
msg.onend = function () {
timer(1);
$('#speak').attr('data-opt', 'speak');
};
msg.onerror = function(event){
if(navigator.userAgent.search('Mobile') == -1){
alert('An error has occurred with the speech synthesis: ' + event.error);
}else{
console.log('An error has occurred with the speech synthesis: ' + event.error);
}
timer(1);
window.speechSynthesis.cancel();
$('#speak').attr('data-opt', 'speak');
};
$.when(window.speechSynthesis.speak(msg)).then(function () {
$('#speak').attr('data-opt', 'cancel');
});
}
Краткое объяснение моего кода: когда вы нажимаете кнопку #speak, в первую очередь функция обратного вызова начинает фильтровать, поддерживает ли этот браузер API веб-речи, и если этот браузер является хромом, после прохождения всей фильтрации он получает текст из свойства innerText текущей страницы. и, наконец, произнесите текст.
Кажется, он отлично работает, в большинстве случаев отлично работает на рабочем столе.
Проблема, с которой я столкнулся, заключается в том, что он просто перестает работать на мобильных устройствах, особенно на iOS, после произнесения всего текста или иногда случайного, я не знаю, почему он так внезапно останавливается без каких-либо ошибок.
Поскольку я написал функцию таймера, я не думаю, что это типичная проблема, возникающая с длинным текстом.
Любая помощь будет оценена заранее спасибо.
msg.onend
возможно, проблема, см. event-in-chromiu" title="почему синтез речи иногда не запускает конечное событие в chromiu">stackoverflow.com/questions/54861046/ - person Snow   schedule 21.08.2019SpeechSynthesisUtterance
в полупостоянной внешней переменной (на которую ссылаются в нескольких местах), чтобы предотвратить преждевременную сборку мусора. - person Snow   schedule 22.08.2019