Is there a way to auto play audio in React without using an onClick event?

Viewed 9668

I'm getting this error when trying to play audio within componentDidMount. 'Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.'

componentDidMount() {
  document.getElementById("backgroundMusic").play();
}

<audio id="backgroundMusic">
<source src={url} type="audio/mpeg" />
Your browser does not support the audio element.
</audio>

It works fine with an onclick event. Is there any way to autoPlay audio in React? I thought I could trigger the audio to start by using onMouseOver, but ideally the music would just start without any user interaction.

3 Answers

Autoplay Policy Changes no longer allow autoplay without user interaction first.

  • Muted autoplay is always allowed.
  • Autoplay with sound is allowed if:
    • User has interacted with the domain (click, tap, etc.).
    • On desktop, the user's Media Engagement Index threshold has been crossed, meaning the user has previously played video with sound.
    • The user has added the site to their home screen on mobile or installed the PWA on desktop.
  • Top frames can delegate autoplay permission to their iframes to allow autoplay with sound.

The only way to bypass this would be your mouse movement implementation

The error message you've got is pretty much self-explaining. Most of the modern browsers prevent audio/video autoplay before user interaction with the page. They do so to avoid certain undesired effects for the user (for instance, a user might have maximum audio volume set & auto-playing loud audio might surprise/scare her).

There are certain hacks you can try out, but none is really guaranteed to work cross-browser.

I fixed this by catching the error and play the sound after the first click. In your code, that would be something like this:

componentDidMount() {
  document.getElementById("backgroundMusic").play().catch((error) => {
    document.addEventListener('click', () => {
      document.getElementById("backgroundMusic").play()
    }, { once: true } )
}

<audio id="backgroundMusic">
<source src={url} type="audio/mpeg" />
Your browser does not support the audio element.
</audio>

This way, you're compliant with the Autoplay Policy Changes mentioned by Halmond and you stay away from hacky solutions referenced by Igor.

Related