Iframe autoplay not working in Chrome
Autoplay policy in ChromeImproved user experience, minimized incentives to install ad blockers, and reduced data consumption Show Published on Wednesday, September 13, 2017 Updated on Tuesday, May 25, 2021 François Beaufort Dives into Chromium source code The Autoplay Policy launched in Chrome 66 for audio and video elements and is effectively blocking roughly half of unwanted media autoplays in Chrome. For the Web Audio API, the autoplay policy launched in Chrome 71. This affects web games, some WebRTC applications, and other web pages using audio features. More details can be found in the Web Audio API section below. Chrome's autoplay policies changed in April of 2018 and I'm here to tell you why and how this affects video playback with sound. Spoiler alert: users are going to love it! # New behaviorsAs you may have noticed, web browsers are moving towards stricter autoplay policies in order to improve the user experience, minimize incentives to install ad blockers, and reduce data consumption on expensive and/or constrained networks. These changes are intended to give greater control of playback to users and to benefit publishers with legitimate use cases. Chrome's autoplay policies are simple:
# Media Engagement IndexThe Media Engagement Index (MEI) measures an individual's propensity to consume media on a site. Chrome's approach is a ratio of visits to significant media playback events per origin:
From that, Chrome calculates a media engagement score, which is highest on sites where media is played on a regular basis. When it is high enough, media is allowed to autoplay on desktop only. A user's MEI is available at the about://media-engagement internal page. # Developer switchesAs a developer, you may want to change Chrome autoplay policy behavior locally to test your website for different levels of user engagement.
# Iframe delegationA permissions policy allows developers to selectively enable and disable browser features and APIs. Once an origin has received autoplay permission, it can delegate that permission to cross-origin iframes with the permissions policy for autoplay. Note that autoplay is allowed by default on same-origin iframes. <iframe src="https://cross-origin.com/myvideo.html" allow="autoplay"> <iframe src="https://cross-origin.com/myvideo.html" allow="autoplay; fullscreen"> When the permissions policy for autoplay is disabled, calls to play() without a user gesture will reject the promise with a NotAllowedError DOMException. And the autoplay attribute will also be ignored. Warning Older articles incorrectly recommend using the attribute gesture=media which is not supported. # ExamplesExample 1: Every time a user visits VideoSubscriptionSite.com on their laptop they watch a TV show or a movie. As their media engagement score is high, autoplay is allowed. Example 2: GlobalNewsSite.com has both text and video content. Most users go to the site for text content and watch videos only occasionally. Users' media engagement score is low, so autoplay wouldn't be allowed if a user navigates directly from a social media page or search. Example 3: LocalNewsSite.com has both text and video content. Most people enter the site through the homepage and then click on the news articles. Autoplay on the news article pages would be allowed because of user interaction with the domain. However, care should be taken to make sure users aren't surprised by autoplaying content. Example 4: MyMovieReviewBlog.com embeds an iframe with a movie trailer to go with a review. Users interacted with the domain to get to the blog, so autoplay is allowed. However, the blog needs to explicitly delegate that privilege to the iframe in order for the content to autoplay. # Chrome enterprise policiesIt is possible to change the autoplay behavior with Chrome enterprise policies for use cases such as kiosks or unattended systems. Check out the Policy List help page to learn how to set the autoplay related enterprise policies:
# Best practices for web developers# Audio/Video elementsHere's the one thing to remember: Don't ever assume a video will play, and don't show a pause button when the video is not actually playing. It is so important that I'm going to write it one more time below for those who simply skim through that post. Gotchas Don't assume a video will play, and don't show a pause button when the video is not actually playing. You should always look at the Promise returned by the play function to see if it was rejected: var promise = document.querySelector('video').play();if (promise !== undefined) { promise.then(_ => { // Autoplay started! }).catch(error => { // Autoplay was prevented. // Show a "Play" button so that user can start playback. }); } Caution Don't play interstitial ads without showing any media controls as they may not autoplay and users will have no way of starting playback. One cool way to engage users is to use muted autoplay and let them chose to unmute. (See the example below.) Some websites already do this effectively, including Facebook, Instagram, Twitter, and YouTube. <video id="video" muted autoplay><button id="unmuteButton">button> <script> unmuteButton.addEventListener('click', function() { video.muted = false; }); script> Events that trigger user activation are still to be defined consistently across browsers. I'd recommend you stick to "click" for the time being then. See GitHub issue whatwg/html#3849. # Web AudioThe Web Audio API has been covered by autoplay since Chrome 71. There are a few things to know about it. First, it is good practice to wait for a user interaction before starting audio playback so that users are aware of something happening. Think of a "play" button or "on/off" switch for instance. You can also add an "unmute" button depending on the flow of the app. If an AudioContext is created before the document receives a user gesture, it will be created in the "suspended" state, and you will need to call resume() after the user gesture. If you create your AudioContext on page load, you'll have to call resume() at some time after the user interacted with the page (e.g., after a user clicks a button). Alternatively, the AudioContext will be resumed after a user gesture if start() is called on any attached node. // Existing code unchanged.window.onload = function() { var context = new AudioContext(); // Setup all nodes // ... } // One-liner to resume playback when user interacted with the page. document.querySelector('button').addEventListener('click', function() { context.resume().then(() => { console.log('Playback resumed successfully'); }); }); You may also create the AudioContext only when the user interacts with the page. document.querySelector('button').addEventListener('click', function() {var context = new AudioContext(); // Setup all nodes // ... }); To detect whether the browser requires a user interaction to play audio, check AudioContext.state after you've created it. If playing is allowed, it should immediately switch to running. Otherwise it will be suspended. If you listen to the statechange event, you can detect changes asynchronously. To see an example, check out the small Pull Request that fixes Web Audio playback for these autoplay policy rules for https://airhorner.com. You can find a summary of Chrome's autoplay feature on the Chromium site. Autoplay Media Last updated: Tuesday, May 25, 2021 Improve article |