use a mock btn to start the speak works for me.
be careful to check the page is muted or not, which took me some hrs to find the bug.(when the page is muted, the speak() method will return an error "not-allowed")
speak(message: string): Observable<string> {
return new Observable(observer => {
const callback = () => {
const utterance = new SpeechSynthesisUtterance(message);
utterance.voice = speechSynthesis.getVoices().find((voice) => voice.lang === 'zh-CN' && voice.localService === true);
utterance.onend = () => {
console.log('TTS_SPEAK', message);
observer.next(message);
observer.complete();
};
utterance.onerror = (err) => {
if(err.error === 'not-allowed') {
this.msg.warning('The page is muted');
}
observer.error(err)
};
window.speechSynthesis?.speak(utterance);
}
if (!window.navigator.userAgent.includes('Edg') && window.navigator.userAgent.includes('Chrome')) {
// https://stackoverflow.com/questions/41539680/speechsynthesis-speak-not-working-in-chrome
// https://chromestatus.com/feature/5687444770914304
const btn = document.createElement('button');
btn.style.display = 'none';
btn.id = 'TTS_btn';
btn.addEventListener('click', () => {
callback();
});
document.body.appendChild(btn);
let event = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
})
btn.dispatchEvent(event);
document.body.removeChild(btn);
} else {
callback();
}
});
}