How to handle "Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first." on Desktop with Chrome 66?
Solution 1
To make the autoplay on html 5 elements work after the chrome 66 update you just need to add the muted
property to the video element.
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
For me (in Angular project) this code helped:
In HTML you should add autoplay muted
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
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
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
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.
Related videos on Youtube
Comments
-
Steven about 2 years
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"
, andautoplay=""
attributes to the<video>
element? Are there any negative consequences to this?-
MaddTheSane about 6 yearsI think playsinline is an iOS thing.
-
nbar over 2 years@everyone: How is youtube able to bypass the "no userinteraction" rule?
-
Carson over 2 yearsThis link may helpful developer.chrome.com/blog/autoplay
-
-
Ceddy Muhoza about 6 yearsThis actually did the trick, i was doing SSR with nextjs... why the down votes tho?
-
Ming about 6 yearsAutoplay Policy Changes. Click me
-
DesTroy about 6 yearsYou can't possibly ask each and every user to go an change the settings .
-
Tuan Nguyen almost 6 yearsIt only use for developer to test Chrome autoplay policy behaviour locally. developers.google.com/web/updates/2017/09/…
-
nickiaconis almost 6 yearsIs there a programmatic way to achieve this? I have automated tests running in headless Chrome that are now failing due to this policy. I've tried passing a few different command line flags via Testem to no avail.
-
nickiaconis almost 6 yearsI found that the command line flag
--autoplay-policy=no-user-gesture-required
is the programmatic way to achieve this setting. -
koosa over 5 yearsThis only works for your browser, everybody else will still be affected
-
adripanico over 5 yearsWho is upvoting this answer? This is not superuser.com. A solution for your local machine cannot be an acceptable answer.
-
nikitahl over 5 yearsIs there a way to enable audio right after the video starts playing? Removing the
mute
attribute or settingvolume
attribute doesn't help. -
Kamil Kiełczewski about 5 yearsOn MacOs Chrome Version 74.0.3729.131 both snippets give black screen
-
Joe about 5 years@KamilKiełczewski The video was showing a black screen because the
src
was invalid. I have updated the snippetsrc
so the video auto plays. -
Milan Švehla over 4 yearsThis could solve the issue for some people actually (kiosks, private and local websites...), but the flag was removed in Chrome 76. Now the only solution is this answer
-
Pedro Ferreira over 4 yearsAbsolutely true and unbelievable, even with Ng8, latest Angular version. Angular simply doesn't care about what's going on component's HTML template!
-
Pedro Ferreira over 4 yearsAnd, with the new Angular's way of using
@ViewChild()
you need to set sttatic option to true:@ViewChild('videoPlayer', {static: true}) videoplayer: ElementRef;
video: HTMLVideoElement;
And then:this.video = this.videoplayer.nativeElement;
@ngOnInit()
-
Ignacio Bustos over 4 yearsThis was my issue, muted in HTML is completely ignored and I had to force it by JS. + 1M to your answer after days searching
-
tgordon18 about 4 yearsI had to do
muted="true"
instead -
Marinpietri about 4 yearsThat's it the answer. thks
-
Panagiss almost 4 yearsit's better to set
muted=true
ORmuted=false
-
Joe almost 4 years@Panagiss I would say do
muted="muted"
ormuted="true"
Both work for me. -
arao6 almost 4 yearsWow, can't believe I actually needed the javascript-side muting for Angular SSR post-load views. This whole time, I thought the HTML was the problem.
-
loretoparisi almost 4 yearsThis is a very clever approach, that does not break any policy (since playback does not start anyways), and prevents to have errors. +1
-
john Smith almost 4 yearsi guess you could be able to trigger gesture programmatically ? anybody?``
-
Kaiido over 3 years@JanTuroň no you can't.
.play
and.pause
methods need to be called from the HTMLMediaElement instance directly, or you need to create a bound copy of the method, e.gvid.play.then(vid.pause.bind(vid))
, which is not really easier to read than the simplevid.play.then(()=>vid.pause())
. -
Andrews Gomes over 3 yearsNão funciona testei no chrome Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first
-
Sylvain Lesage over 3 yearsNote that MDN has an excellent page dedicated to autoplay (developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide): why it might be blocked by the browser, how to avoid being blocked, alternative ways to autoplay, how to apply a policy, best practices
-
Black over 3 yearsYou can also just write
muted
works at least for me. -
Bernesto about 3 yearsThis suggestion should be removed as it does not address the original posters issue, and does not address the issue at large for any machine other than your own.
-
Gamer In The Game almost 3 yearsI have this problem with <audio> element, how can I solve it ?
-
TefoD almost 3 yearsDito. Preventing errors and any policies was as well my goal. Any sound can wait till user interacts - just great!
-
almaruf over 2 yearsMay be this is not exactly what the OP wanted but this can resolve my issue as in our case the browser is in Kiosk mode and we will be managing the browser - so thanks for this.
-
akaravashkin over 2 yearsThis is only correct answer! Thank you, helped me a lot.
-
Ajeet Eppakayala about 2 yearsCould you please check if things are still as you said? I am using chrome and nothing works as you said. For fiddle, I had to click inside the Iframe(not on the video) then "run" to play the video. And snippet is not working too.
-
mergen about 2 yearsDoesn't work anymore in Chrome (tested against version 100.0.4896.127). Edit: mousemove works after performing a click once.