Skip to content

Instantly share code, notes, and snippets.

@AshKyd
Last active January 12, 2024 03:19
Show Gist options
  • Save AshKyd/d75f7e342718de6dcfc8561e6efb0c77 to your computer and use it in GitHub Desktop.
Save AshKyd/d75f7e342718de6dcfc8561e6efb0c77 to your computer and use it in GitHub Desktop.
Failsafe way to programmatically play a video, falling back to muted

https://developer.chrome.com/blog/autoplay

  1. Safari will not autoplay any videos when in low power mode.
    1. Requires a user interaction, after which the remainder of autoplay videos in the page work fine.
    2. Interaction means some form of click interaction. Doesn't even matter on what.
    3. Attempting to trigger an unumuted video with the element.play() api only works after interaction. Attempting this without an interaction will throw immediately, it does NOT return a rejected promise.
    4. It's not straightforward to detect the low power behaviour happening because Safari runs through all the standard video events as if the video is playing correclty. But the very last event will be "paused" which we can use to show a button to start the interactive.
  2. Chrome will always play muted autoplay videos.
  3. Attempting to play an unmuted video in Chrome with element.play() will return a rejected promise.

The following code will attempt to play a video, falling back to a muted video:

/**
* Try to play a video, falling back to a muted video.
* @param {HTMLMediaElement} video
*/
async function tryPlay(video) {
try {
await video.play();
} catch (e) {
video.setAttribute('muted', 'true');
try {
await video.play();
} catch (e) {
console.log('could not play muted video.');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment