Undefined SpeechSynthUtterance error on Firefox Android

192 views Asked by At

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?

0

There are 0 answers