How to handle "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first." on Desktop with Chrome 66?

JavascriptGoogle ChromeVideoHtml5 Video

Javascript Problem Overview


I'm getting the error message..

> Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

..when trying to play video on desktop using Chrome version 66.

I did find an ad that began playback automatically on a website however using the following HTML:

<video
    title="Advertisement"
    webkit-playsinline="true"
    playsinline="true"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="http://ds.serving-sys.com/BurstingRes/Site-2500/Type-16/1ff26f6a-aa27-4b30-a264-df2173c79623.mp4"
    autoplay=""></video>

So is by-passing Chrome v66's autoplay blocker really as easy as just adding the webkit-playsinline="true", playsinline="true", and autoplay="" attributes to the <video> element? Are there any negative consequences to this?

Javascript Solutions


Solution 1 - Javascript

To make the autoplay on html 5

So your current video HTML

<video
    title="Advertisement"
    webkit-playsinline="true"
    playsinline="true"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
    autoplay=""></video>

Just needs muted="muted"

<video
    title="Advertisement"
    style="background-color: rgb(0, 0, 0); position: absolute; width: 640px; height: 360px;"
    src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
    autoplay="true"
    muted="muted"></video>

I believe the chrome 66 update is trying to stop tabs creating random noise on the users tabs. That's why the muted property make the autoplay work again.

Solution 2 - Javascript

For me (in Angular project) this code helped:

In HTML

In JS/TS

playVideo() {
    const media = this.videoplayer.nativeElement;
    media.muted = true; // without this line it's not working although I have "muted" in HTML
    media.play();
}

Solution 3 - Javascript

Try to use mousemove event listener

var audio = document.createElement("AUDIO")
document.body.appendChild(audio);
audio.src = "./audio/rain.m4a"

document.body.addEventListener("mousemove", function () {
    audio.play()
})

Solution 4 - Javascript

The best solution i found out is to mute the video

HTML

<video loop muted autoplay id="videomain">
  <source src="videoname.mp4" type="video/mp4">
</video>

Solution 5 - Javascript

Answering the question at hand...
No it's not enough to have these attributes, to be able to autoplay a media with audio you need to have an user-gesture registered on your document.

But, this limitation is very weak: if you did receive this user-gesture on the parent document, and your video got loaded from an iframe, then you could play it...

So take for instance this fiddle, which is only

<video src="myvidwithsound.webm" autoplay=""></video>

At first load, and if you don't click anywhere, it will not run, because we don't have any event registered yet.
But once you click the "Run" button, then the parent document (jsfiddle.net) did receive an user-gesture, and now the video plays, even though it is technically loaded in a different document.

But the following snippet, since it requires you to actually click the Run code snippet button, will autoplay.

<video src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" autoplay=""></video>

This means that your ad was probably able to play because you did provide an user-gesture to the main page.


Now, note that Safari and Mobile Chrome have stricter rules than that, and will require you to actually trigger at least once the play() method programmatically on the <video> or <audio> element from the user-event handler itself.

btn.onclick = e => {
  // mark our MediaElement as user-approved
  vid.play().then(()=>vid.pause());
  // now we can do whatever we want at any time with this MediaElement
  setTimeout(()=> vid.play(), 3000);
};

<button id="btn">play in 3s</button>
<video
  src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" id="vid"></video>

And if you don't need the audio, then simply don't attach it to your media, a video with only a video track is also allowed to autoplay, and will reduce your user's bandwidth usage.

Solution 6 - Javascript

Extend the DOM Element, Handle the Error, and Degrade Gracefully

Below I use the prototype function to wrap the native DOM play function, grab its promise, and then degrade to a play button if the browser throws an exception. This extension addresses the shortcoming of the browser and is plug-n-play in any page with knowledge of the target element(s).

// JavaScript
// Wrap the native DOM audio element play function and handle any autoplay errors
Audio.prototype.play = (function(play) {
return function () {
  var audio = this,
      args = arguments,
      promise = play.apply(audio, args);
  if (promise !== undefined) {
    promise.catch(_ => {
      // Autoplay was prevented. This is optional, but add a button to start playing.
      var el = document.createElement("button");
      el.innerHTML = "Play";
      el.addEventListener("click", function(){play.apply(audio, args);});
      this.parentNode.insertBefore(el, this.nextSibling)
    });
  }
};
})(Audio.prototype.play);

// Try automatically playing our audio via script. This would normally trigger and error.
document.getElementById('MyAudioElement').play()

<!-- HTML -->
<audio id="MyAudioElement" autoplay>
  <source src="https://www.w3schools.com/html/horse.ogg" type="audio/ogg">
  <source src="https://www.w3schools.com/html/horse.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

Solution 7 - Javascript

According to the new browser policy, the user must interact with DOM first before playing the Audio element.

If you want to play the media on page load then you can simply add autoplay property to audio element in HTML like this

<video id="video" src="./music.mp4" autoplay>

or if you don't want to do autoplay then you can handle this using Javascript. Since the autoplay property is set to true, media will be played, we can simply mute the media.

document.getElementById('video').autoplay = true;
document.getElementById('video').muted = true; 

Imp: Now Whenever you play the media don't forget to turn the muted property to false. Like this

document.getElementById('video').muted = false; 
document.getElementById('video').play();

Or you can also show a simple popup where the user will click the allow button in the modal. So he interacts with DOM first, then you don't need anything to do

Solution 8 - Javascript

I got this error

> Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

And here's what I did in my Angular Project

> Key Point: Don't ever 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:

ngOnInit(): void{
    this.ensureVideoPlays();
}

private ensureVideoPlays(): void{
    const video = document.querySelector("video");

    if(!video) return;
    
    const promise = video.play();
    if(promise !== undefined){
        promise.then(() => {
            // Autoplay started
        }).catch(error => {
            // Autoplay was prevented.
            video.muted = true;
            video.play();
        });
    }
}

Source: Autoplay policy

Solution 9 - Javascript

In my case, I had to do this

 // Initialization in the dom
 // Consider the muted attribute
 <audio id="notification" src="path/to/sound.mp3" muted></audio>


 // in the js code unmute the audio once the event happened
 document.getElementById('notification').muted = false;
 document.getElementById('notification').play();

Solution 10 - Javascript

I had a similar problem, I need to play the video without muting it. The way i did this, wait for a second then triggered the event by button. Here is my code

if (playVideo == '1') {
	setTimeout(function() {
		$("#watch_video_btn").trigger('click');
	}, 1000);
}

Solution 11 - Javascript

  1. Open chrome://settings/content/sound
  2. Setting No user gesture is required
  3. Relaunch Chrome

Solution 12 - Javascript

Chrome needs a user interaction for the video to be autoplayed or played via js (video.play()). But the interaction can be of any kind, in any moment. If you just click random on the page, the video will autoplay. I resolved then, adding a button (only on chrome browsers) that says "enable video autoplay". The button does nothing, but just clicking it, is the required user interaction for any further video.

Solution 13 - Javascript

I had some issues playing on Android Phone. After few tries I found out that when Data Saver is on there is no auto play:

There is no autoplay if Data Saver mode is enabled. If Data Saver mode is enabled, autoplay is disabled in Media settings.

Source

Solution 14 - Javascript

I encountered a similar error with while attempting to play an audio file. At first, it was working, then it stopped working when I started using ChangeDetector's markForCheck method in the same function to trigger a re-render when a promise resolves (I had an issue with view rendering).

When I changed the markForCheck to detectChanges it started working again. I really can't explain what happened, I just thought of dropping this here, perhaps it would help someone.

Solution 15 - Javascript

You should have added muted attribute inside your videoElement for your code work as expected. Look bellow ..

<video id="IPcamerastream" muted="muted" autoplay src="videoplayback%20(1).mp4" width="960" height="540"></video>

Don' t forget to add a valid video link as source

Solution 16 - Javascript

Audio Autoplay property does not work in MS Edge

Solution 17 - Javascript

I changed my UI to have the user press a button to load the website (and when the website loads after they click the button, the audio plays)

Since they interact with the DOM, then the audio plays!!!

Solution 18 - Javascript

Type Chrome://flags in the address-bar

Search: Autoplay

> ## Autoplay Policy > Policy used when deciding if audio or video is allowed > to autoplay. > >– Mac, Windows, Linux, Chrome OS, Android

Set this to "No user gesture is required"

Relaunch Chrome and you don't have to change any code

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStevenView Question on Stackoverflow
Solution 1 - JavascriptJoeView Answer on Stackoverflow
Solution 2 - JavascriptEutrepeView Answer on Stackoverflow
Solution 3 - Javascript時雨初View Answer on Stackoverflow
Solution 4 - JavascriptMoizView Answer on Stackoverflow
Solution 5 - JavascriptKaiidoView Answer on Stackoverflow
Solution 6 - JavascriptBernestoView Answer on Stackoverflow
Solution 7 - Javascriptpranav shindeView Answer on Stackoverflow
Solution 8 - JavascriptjnaView Answer on Stackoverflow
Solution 9 - JavascriptShobiView Answer on Stackoverflow
Solution 10 - JavascriptAlauddin AhmedView Answer on Stackoverflow
Solution 11 - JavascriptMingView Answer on Stackoverflow
Solution 12 - JavascriptAlarikView Answer on Stackoverflow
Solution 13 - JavascriptIdoView Answer on Stackoverflow
Solution 14 - JavascriptKing James EnejoView Answer on Stackoverflow
Solution 15 - JavascriptGNETO DOMINIQUEView Answer on Stackoverflow
Solution 16 - JavascriptBahaa SalaheldinView Answer on Stackoverflow
Solution 17 - JavascriptJesus is LordView Answer on Stackoverflow
Solution 18 - JavascriptDARKSETH23View Answer on Stackoverflow