8

is there a way to detect if calling play() on a video element is allowed without a user gesture? On Android Chrome this warning is given:

Failed to execute 'play' on 'HTMLMediaElement': API can only be initiated by a user gesture.

So on Chrome Android a user gesture is required to start the playback of a video, while it isn't on desktop Chrome. Is there a way to detect which behavior I will get?

I want to have slightly different behavior in my app depending on if calling play programatically is allowed or not.

I have tried to use Modernizr.videoautoplay, but that checks if the autoplay property on the element, which is not the same thing. This gives false negatives for IE11 and Edge.

Edit: added an example. The video will start playing automatically in Chrome desktop and IE11 or Edge (with 3s delay) on windows 8 or 10. For Chrome@Android a user interaction is needed (clicking the button) and the error message can be seen in the console.

oskbor
  • 1,592
  • 18
  • 35
  • can you post a code example that has that error? – Patrick Sep 20 '15 at 06:47
  • Hi @Patrick I have updated the question with a link to an example. Its a bit complex (adding frames to the video bit by bit) but the issue can be seen – oskbor Sep 21 '15 at 15:19
  • Hi @oskbor, did you get a fix for this? – Novice Dec 15 '15 at 17:26
  • Nope, did not find a way to detect that – oskbor Dec 15 '15 at 17:27
  • I ended up just filtering var isMobile = false; if ((/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())) || (/Mobi/i.test(navigator.userAgent.toLowerCase()))) isMobile = true; – MrPHP Apr 17 '16 at 07:24

1 Answers1

5

The play method returns a promise which can be used to catch the error.

Not all browsers follow the specification so you will have to check if what is returned is a promise first.

var autoPlayAllowed = true;
var promise = document.createElement("video").play();
if(promise instanceof Promise) {
    promise.catch(function(error) {
        // Check if it is the right error
        if(error.name == "NotAllowedError") {
            autoPlayAllowed = false;
        } else {
            throw error;
        }
    }).then(function() {
        if(autoPlayAllowed) {
            // Allowed
        } else {
            // Not allowed
        }
    });
} else {
    // Unknown if allowed
}
metarmask
  • 1,747
  • 1
  • 16
  • 20
  • 1
    I think this needs to check whether `window.Promise` exists first, otherwise you'll get a reference error on browsers that don't support promises. – JayPea Jul 19 '17 at 22:40
  • This doesn't work on Chrome 70. Without a source set on the video element the promise hangs and doesn't resolve. – Noishe Nov 21 '18 at 19:26