Autoplay audio html not working

I have tried to add audio to a webpage of mine which is supposed to run automatically once the page is loaded, but it doesn't work.

Feedback
 
 

Please provide the following information

Enter your name:*

Address:*

City:*

Mobile:*



How much would you rate this website?*


Comments:*


What I have tried:

I have tried starting the audio via javascript, but I get the error:

Uncaught TypeError: Cannot read property 'play' of null

The script:


Feedback
 
 

Please provide the following information

Enter your name:*

Address:*

City:*

Mobile:*



How much would you rate this website?*


Comments:*


To optimise pages on this blog I recently replaced the animated GIFs with auto-playing videos. It required a couple tries to get it right, so here’s how it works.

The video below won’t autoplay.

<video autoplay>
    <source src="video.mp4" type="video/mp4" />
</video>

To fix this we add the muted attribute, this will disable the audio, making the video less intrusive.

<video autoplay muted>
    <source src="video.mp4" type="video/mp4" />
</video>

However the video above still won’t autoplay on iOS Safari, Safari requires us to add the playsinline attribute.

<video autoplay muted playsinline>
    <source src="video.mp4" type="video/mp4" />
</video>

We can try to hack around these autoplay limitations with some JavaScript, but that will only work if the JavaScript is run as a result of a user action.

Automatically starting the playback of audio (or videos with audio tracks) immediately upon page load can be an unwelcome surprise to users. While autoplay of media serves a useful purpose, it should be used carefully and only when needed. In order to give users control over this, browsers often provide various forms of autoplay blocking. In this guide, we'll cover autoplay functionality in the various media and Web Audio APIs, including a brief overview of how to use autoplay and how to work with browsers to handle autoplay blocking gracefully.

Autoplay blocking is not applied to

audioElement.play();
7 elements when the source media does not have an audio track, or if the audio track is muted. Media with an active audio track are considered to be audible, and autoplay blocking applies to them. Inaudible media are not affected by autoplay blocking.

The term autoplay refers to any feature that causes audio to begin to play without the user specifically requesting that playback begin. This includes both the use of HTML attributes to autoplay media as well as the user of JavaScript code to start playback outside the context of handling user input.

That means that both of the following are considered autoplay behavior, and are therefore subject to the browser's autoplay blocking policy:

<audio src="/music.mp3" autoplay></audio>

and

audioElement.play();

The following web features and APIs may be affected by autoplay blocking:

  • The HTML
    audioElement.play();
    
    8 and
    audioElement.play();
    
    7 elements
  • The Web Audio API

From the user's perspective, a web page or app that spontaneously starts making noise without warning can be jarring, inconvenient, or off-putting. Because of that, browsers generally only allow autoplay to occur successfully under specific circumstances.

As a general rule, you can assume that media will be allowed to autoplay only if at least one of the following is true:

  • The audio is muted or its volume is set to 0
  • The user has interacted with the site (by clicking, tapping, pressing keys, etc.)
  • If the site has been allowlisted; this may happen either automatically if the browser determines that the user engages with media frequently, or manually through preferences or other user interface features
  • If the autoplay Permissions Policy is used to grant autoplay support to an
    <audio id="musicplayer" autoplay>
      <source src="/music/chapter1.mp3" />
    </audio>
    
    0 and its document.

Otherwise, the playback will likely be blocked. The exact situations that result in blocking, and the specifics of how sites become allowlisted vary from browser to browser, but the above are good guidelines to go by.

For details, see the autoplay policies for Google Chrome and WebKit.

Note: Put another way, playback of any media that includes audio is generally blocked if the playback is programmatically initiated in a tab which has not yet had any user interaction. Browsers may additionally choose to block under other circumstances.

Now that we've covered what autoplay is and what can prevent autoplay from being allowed, we'll look at how your website or app can automatically play media upon page load, how to detect when autoplay fails to occur, and tips for coping when autoplay is denied by the browser.

The simplest way to automatically play content is to add the attribute to your

audioElement.play();
8 or
audioElement.play();
7 element. This sets the
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 property on the element to
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5, and when
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 is
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5, the media will automatically begin to play as soon as possible after the following have occurred:

  • The page is allowed to use autoplay functionality
  • The element has been created during page load
  • Enough media has been received to begin playback and continue to play through to the end of the media without interruption, assuming there are no dramatic changes in network performance or bandwidth.

Example: The autoplay attribute

An

audioElement.play();
8 element using the
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 attribute might look like this:

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>

Example 2: Detecting autoplay failure

If you rely on autoplay for anything important, or if autoplay failure will impact your app in any way, you will probably want to be able to tell when autoplay didn't begin. Unfortunately, in the case of the attribute, recognizing whether or not autoplay successfully began is tricky. There's not an event triggered when autoplay fails. Nor is there an exception thrown or a callback you can set up or even a flag on the media element that tells you if autoplay worked. All you can really do is examine a few values and make an educated guess as to whether or not autoplay worked.

A better approach, if you're able to adjust the direction you look at things from, is to instead rely on knowing that playback of the media has successfully started, instead of when it fails to start. You can do this easily, by listening for the

<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
1 event to be fired on the media element.

The

<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
1 event is sent both when the media is resumed after being paused and when autoplay occurs. That means that the first time the
<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
1 event is fired, you know your media is being started for the first time after the page is opened.

Consider this HTML for a media element:

<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>

Here we have a

audioElement.play();
7 element whose attribute is set, with an
<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
6 event handler set up; the event is handled by a function called
<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
7, which receives as input the
<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
1 event.

<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
7 looks like this:

let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}

After getting a reference to the video element from the

let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
0 object's
let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
1, the element's
<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
6 handler is set to
let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
3. This will prevent any future
<video src="myvideo.mp4" autoplay onplay="handleFirstPlay(event)"></video>
1 events from being delivered to the handler. That could happen if the video is paused and resumed by the user or automatically by the browser when the document is in a background tab.

At this point, your site or app can begin whatever it needs to do that relies upon the video having been started up.

Note: This approach doesn't differentiate between autoplay and the user starting playback manually.

The term "autoplay" also refers to scenarios in which a script tries to trigger the playback of media that includes audio, outside the context of handling a user input event. This is done by calling the media element's

let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 method.

Note: It is strongly recommended that you use the

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 attribute whenever possible, because support for autoplay preferences are more widespread for the
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 attribute than for other means of playing media automatically. It also lets the browser take responsibility for starting playback, letting it optimize the timing of that taking place.

Example: Playing video

This simple example plays the first

audioElement.play();
7 element found in the document.
let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 won't let the playback begin unless the document has permission to automatically play media.

document.querySelector("video").play();

Example: Handling play() failures

It's much easier to detect a failure to autoplay media when you use the

let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 method to start it.
let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 returns a
document.querySelector("video").play();
2 which is resolved once the media successfully begins to play, and is rejected when playback fails to begin (such as if autoplay is denied). When autoplay fails, you likely will want to offer a way for the user to manually tell the browser to ask the user to grant permission to play media.

You might use code like this to accomplish the job:

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}

The first thing we do with the result of

let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 is make sure it's not
document.querySelector("video").play();
4. We check for this because in earlier versions of the HTML specification,
let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 didn't return a value. Returning a promise to allow you to determine success or failure of the operation was added more recently. Checking for
document.querySelector("video").play();
4 prevents this code from failing with an error on older versions of web browsers.

If the promise returned by

let hasPlayed = false;
function handleFirstPlay(event) {
  if (!hasPlayed) {
    hasPlayed = true;

    const vid = event.target;

    vid.onplay = null;

    // Start whatever you need to do after first playback has started
  }
}
5 is resolved without error, the
document.querySelector("video").play();
8 clause is run and can begin whatever needs to be done when autoplay has begun.

We then add a

document.querySelector("video").play();
9 handler to the promise. This looks at the error's
let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
0 to see if it's
let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
1. This indicates that playback failed due to a permission issue, such as autoplay being denied. If that's the case, we should present a user interface to let the user manually start playback; that's handled here by a function
let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
2.

Any other errors are handled as appropriate.

If you want to start playing the video after the first interaction with the page,

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
3 might be used to achieve this:

let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);

In the Web Audio API, a website or app can start playing audio using the

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
4 method on a source node linked to the
let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
5. Doing so outside the context of handling a user input event is subject to autoplay rules.

In addition to the browser-side management and control over autoplay functionality described above, a web server can also express its willingness to allow autoplay to function. The HTTP

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
6 header's
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 directive is used to control which domains, if any, can be used to autoplay media. By default, the
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 Permissions Policy is set to
let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
9, indicating that autoplay is permitted as they're hosted on the same domain as the document.

You can also specify an empty allowlist (

let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);
0) to disable autoplay entirely,
let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);
1 to allow autoplay from all domains, or one or more specific origins from which media can be automatically played. These origins are separated by space characters.

Note: The specified Permissions Policy applies to the document and every

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0 nested within it, unless those frames include an , which sets a new Permissions Policy for that frame and all frames nested within it.

When using the attribute on an

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0 to specify a Permissions Policy for that frame and its nested frames, you can also specify the value
let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);
6 to allow autoplay of media only from the same domain as that specified by the frame's attribute.

To use the

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
6 header to only allow media to autoplay from the document's origin:

Permissions-Policy: autoplay=(self)

To do the same for an

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0:

<iframe src="mediaplayer.html" allow="autoplay"> </iframe>

Adding Fullscreen API permission to the previous example results in a

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
6 header like the following if fullscreen access is allowed regardless of the domain; a domain restriction can be added as well as needed.

audioElement.play();
0

The same permissions, grated using the

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0 element's
let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);
3 property, look like this:

audioElement.play();
1

The

let startPlayPromise = videoElem.play();

if (startPlayPromise !== undefined) {
  startPlayPromise
    .then(() => {
      // Start whatever you need to do only after playback
      // has begun.
    })
    .catch((error) => {
      if (error.name === "NotAllowedError") {
        showPlayButton(videoElem);
      } else {
        // Handle a load or playback error
      }
    });
}
6 header to allow media to be played from both the document's (or
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0's) own domain and
Permissions-Policy: autoplay=(self)
5 looks like this:

audioElement.play();
2

An

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0 can be written to specify that this autoplay policy should be applied to itself and any child frames would be written thusly:

audioElement.play();
3

Setting the

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
1 Permissions Policy to
let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);
0/
Permissions-Policy: autoplay=(self)
9 disables autoplay entirely for the document or
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0 and all nested frames. The HTTP header is:

audioElement.play();
4

Using the

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
0's
let playAttempt = setInterval(() => {
  videoElem
    .play()
    .then(() => {
      clearInterval(playAttempt);
    })
    .catch((error) => {
      console.log("Unable to play the video, User has not interacted yet.");
    });
}, 3000);
3 attribute:

audioElement.play();
5

Tips and recommended best practices to help you make the most of working with autoplay are offered here.

A common use case for autoplay is to automatically begin to play a video clip that goes along with an article, an advertisement, or a preview of the page's main functionality. To autoplay videos like these, you have two options: don't have an audio track, or have an audio track but configure the

audioElement.play();
7 element to mute the audio by default, like this:

audioElement.play();
6

This video element is configured to include the user controls (typically play/pause, scrubbing through the video's timeline, volume control, and muting); also, since the attribute is included, and the attribute that is required for autoplay in Safari, the video will autoplay but with the audio muted. The user has the option, however, of re-enabling the audio by clicking on the unmute button in the controls.

Browsers may have preferences that control the way autoplay works, or how autoplay blocking is handled. Here, any such preferences that may be of special significance or importance to you as a web developer are listed. These include any that may aid in testing or debugging as well as any that could be set in a way that you need to be prepared to handle.

<iframe src="mediaplayer.html" allow="autoplay"> </iframe>
6

A Boolean preference which specifies whether the

<iframe src="mediaplayer.html" allow="autoplay"> </iframe>
7 property is exposed to the web. This is currently
<iframe src="mediaplayer.html" allow="autoplay"> </iframe>
8 by default (except in nightly builds, where it's
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5 by default). If this is
<iframe src="mediaplayer.html" allow="autoplay"> </iframe>
8, the
audioElement.play();
01 property is missing from the
audioElement.play();
02 interface, and is thus not present on either
audioElement.play();
8 or
audioElement.play();
7 elements.

audioElement.play();
05

This Boolean preference, if

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5, allows browser extensions' background scripts to autoplay audio media. Setting this value to
<iframe src="mediaplayer.html" allow="autoplay"> </iframe>
8 disables this capability. The default value is
<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5.

audioElement.play();
09

A Boolean preference which if

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5 (the default) allows audio media which is currently muted to be automatically played. If this has been changed to
<iframe src="mediaplayer.html" allow="autoplay"> </iframe>
8, media with an audio track will not be permitted to play even if muted.

audioElement.play();
12

A Boolean preference which indicates whether media playback is blocked when started on a background tab. The default value,

<audio id="musicplayer" autoplay>
  <source src="/music/chapter1.mp3" />
</audio>
5, means that even when otherwise available, autoplay won't take place until after a tab is brought to the foreground. This prevents the distracting situation in which a tab begins playing sound and the user can't find the tab among all their tabs and windows.

How do I get HTML to automatically play audio?

The autoplay attribute is a boolean attribute. When present, the audio will automatically start playing as soon as it can do so without stopping.

Why autoplay is not working in HTML?

Chrome does not allow autoplay if the video is not muted. So to autoplay video you need to set both autoplay and muted attribute.

How do I autoplay audio in Chrome HTML?

Just add an invisible iframe with an . mp3 as its source and allow="autoplay" before the audio element. As a result, the browser is tricked into starting any subsequent audio file.

How do I enable autoplay audio in Chrome?

Enable Chrome to allow sound..
Click Lock in the address bar of your Chrome browser..
Click Site Settings..
Under Sound, select Allow..