I’m writing a game where the player interacts using the arrow keys, which can produce audio. This works in all browsers, except Firefox.
Firefox does not seem to count the arrow keys (ArrowUp
, ArrowLeft
, ArrowRight
, ArrowDown
) as valid user gestures, which prevents an audio context from being played. Firefox counts other keys (such as W
/A
/S
/D
) as valid, but not the arrow keys.
The following error is printed in the console:
An AudioContext was prevented from starting automatically. It must be created or resumed after a user gesture on the page.
However, arrow keys are treated as a user gesture in Chrome and Safari, and the audio plays fine.
Is there any known cross-browser solution or workaround that I could use? I know I could just put a button at the start of my game, but my artistic vision of the game just doesn’t have a big start button before you can play.
Perhaps this is a known Firefox bug and I just can’t find it, or perhaps somebody knows a workaround.
TLDR:
Steps to reproduce:
- Go to the demo site
- Press ArrowUp/Down/Left/Right
Expected result: sound will be played in all browsers
Actual result: sound is only played in Safari and Chrome, not Firefox
Demo code:
<code>press a key to see if it sounds: </code>
<script>
const code = document.querySelector('code')
const audioCtx = new AudioContext({})
const oscillatorGainNode = audioCtx.createGain()
oscillatorGainNode.gain.value = 0.2
oscillatorGainNode.connect(audioCtx.destination)
const beep = () => {
const oscillator = audioCtx.createOscillator()
oscillator.type = "square"
oscillator.frequency.value = 220 + ((Math.random() * 9) | 0) * 32
const msDelay = 0
const msDuration = 200
oscillatorGainNode.connect(audioCtx.destination)
oscillator.connect(oscillatorGainNode)
oscillator.start(audioCtx.currentTime + msDelay / 1000)
oscillator.stop(audioCtx.currentTime + msDelay / 1000 + msDuration / 1000)
}
window.onkeydown = (ev=> {
beep()
code.textContent+=ev.key + ' '
})
</script>
The demo is also hosted at this URL:
https://6643defaf1a25706487ec3f8–glittery-dusk-6bb447.netlify.app/