Modernizr: Video autoplay detection is outdated for iOS 10

Created on 24 Feb 2017  Â·  13Comments  Â·  Source: Modernizr/Modernizr

iOS 10 allows autoplaying videos if they have the muted and playsinline attributes. Android Chrome 54+ allows it as well, but not if the video element is created with JavaScript; only if the video element is already in the HTML on page load. I added the following two lines to the JS to get it to work in iOS.

+  elem.setAttribute('muted', '');
   elem.setAttribute('autoplay', '');
+  elem.setAttribute('playsinline', '');

Caveats: 1) iOS and Android do require the two attributes to work, so it might be a good idea to document that, and if someone wants to embed video that will play in fullscreen or with sound, this would give them a false positive, though I can't imagine that situation being all that common; most of the time, the use case for these videos is a silent background video. Nevertheless, it's something to keep in mind. 2) There is no way I've found so far to detect or utilize support on Android without putting the video in the HTML. This is a bummer since sometimes you want to skip loading the video altogether if autoplay isn't supported, especially in the case of background videos.

Most helpful comment

Modernizr seems, dare I say it, in need of modernization...

All 13 comments

Any update here?

I was also wondering why such long test is needed. Isn't the following enough?

function autoplayMutedSupported() {
  var v = document.createElement('video');
  v.muted = true;
  v.play();
  return !v.paused;
}

_Source: https://github.com/whatwg/html/issues/976#issuecomment-259644807._

alekseyg patch didn't work for me, I still get no-autoplay on ipad and iphone IOS10.

@alekseyg , I've tried adding the 2 lines playslinline and muted but modernizr is still not working to detect autoplay for iOS 10. Is it working for you ?

@fmp777 @tinocha If I remember correctly, iOS 10.1 or 10.2 had a few subtle changes that broke it. I believe to get it working again, I may have changed either the mp4 file or some other small thing. In the end, I moved away from Modernizr and adapted the code to a CommonJS module that I've been using in my projects. This issue has been open for so long that I'm not surprised if it's not working any longer. Here's a gist with the full code I am currently using: https://gist.github.com/alekseyg/a100e19322c9d49586d50e45e929b6de

Here's how I use it:

const isAutoplaySupported = require('./isAutoplaySupported')

isAutoplaySupported(supported => {
  if (supported)
    // initialize video
  else
    // initialize slideshow
})

Modernizr seems, dare I say it, in need of modernization...

Furthermore, Safari 11 specifically prevents autoplay on videos who contain an audio track so I reckon the base64 encoded sample video needs to have an audio track for proper detection.

iOS 11 is blocking playback of the dummy video element due to inline style "display:none;". I replaced cssText of "display:none;" with "height=0;width=0;", which did the trick on iOS 11.

@Skadi2k3 Interesting. iOS 11 still works with my gist on the websites I'm using it, and it contains the display:none inline style. What works works, I guess though. ¯\_(ツ)_/¯

@alekseyg But your gist is using elem.play() which you shouldn't use if you want to test the default browser behavior when hitting a video element with autoplay attribute. Now it is a test for autoplay OR can i inject and/or start a video without user interaction using JS. Removing display:none gets rid of the reluctance to start/download videos that can be excluded from rendering/downloading.

@Skadi2k3 Ah, I see. Generally, browsers that block autoplay, block both behaviors, so the test tends to work, and because I want to know which to load beforehand, I do end up injecting the video or slideshow based on the result, so the method works best for my purpose. If a browser blocks autoplay and you just wish to use it as a dynamic background or whatnot, what's the point of downloading the video anyway, especially on a mobile connection? You have a point, but this is just the reasoning behind the functionality in my gist.

@alekseyg Well no need to argue here, when it comes down to testing it on a multitude of devices anyway :)

@Skadi2k3 I don't think we're arguing here at all; just discussing different approaches for different use cases. :)

Was this page helpful?
0 / 5 - 0 ratings