Background
I am creating a simple SpeechSynth
component that runs fine on most devices but somehow on FireFox android the SpeechSynthUtterance
will dispatch the onerror
event with no error property defined on the event.
Voices are loaded; it's not an issue of undefined voices. I can't get to the bottom of this since the error is simply undefined
.
Reproduction
const MAX_LOAD_VOICES = 5
let loadVoiceCount = 0
const loadVoices = (callback) => {
const speech = window.speechSynthesis
const voices = speech.getVoices()
if (voices.length > 0) {
return callback({ speech, voices })
}
if (++loadVoiceCount > MAX_LOAD_VOICES) {
throw new Error(`Failed to load speech synthesis voices, after ${loadVoiceCount} retries.`)
}
return setTimeout(() => loadVoices(callback), 100)
}
loadVoices(({ speech, voices }) => {
const utterance = new window.SpeechSynthesisUtterance('Hello world')
utterance.voice = voices[0] // assume this is the voice we want
utterance.onend = function () {
console.log('SpeechSynth successfully ended')
}
utterance.onerror = function (event) {
console.log('SpeechSynth failed')
console.debug(event)
}
speech.speak(utterance)
})
Expected
This script should run just fine (just try with your browser)
Result on Firefox Android
The utterance.onerror event will be fired with no error defined and no text spoken.
Output of the logged error event (console.debug(event)
):
{
bubbles: false
cancelBubble: false
cancelable: false
charIndex: 0
charLength: null
composed: false
currentTarget: null
defaultPrevented: false
elapsedTime: 0
eventPhase: 0
explicitOriginalTarget: SpeechSynthesisUtterance { text: "Hello world", volume: 1, rate: 1, … }
isTrusted: true
name: ""
originalTarget: SpeechSynthesisUtterance { text: "Hello world", volume: 1, rate: 1, … }
returnValue: true
srcElement: SpeechSynthesisUtterance { text: "Hello world", volume: 1, rate: 1, … }
target: SpeechSynthesisUtterance { text: "Hello world", volume: 1, rate: 1, … }
timeStamp: 2591
type: "error"
utterance: SpeechSynthesisUtterance { text: "Hello world", volume: 1, rate: 1, … }
<get isTrusted()>: function isTrusted()
<prototye>: SpeechSynthesisEventPrototype { utterance: Getter, charIndex: Getter, charLength: Getter, … }
}
The browser compatibility should also be of no issue, since I am running FF Mobile 88.0.1 on Android 11
Am I missing something "special" to create the utterance?