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

367,041

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.

Share:
367,041

Related videos on Youtube

Steven
Author by

Steven

Engineer/Artist

Updated on April 08, 2022

Comments

  • Steven
    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", and autoplay="" attributes to the <video> element? Are there any negative consequences to this?

    • MaddTheSane
      MaddTheSane about 6 years
      I think playsinline is an iOS thing.
    • nbar
      nbar over 2 years
      @everyone: How is youtube able to bypass the "no userinteraction" rule?
    • Carson
      Carson over 2 years
      This link may helpful developer.chrome.com/blog/autoplay
  • Ceddy Muhoza
    Ceddy Muhoza about 6 years
    This actually did the trick, i was doing SSR with nextjs... why the down votes tho?
  • Ming
    Ming about 6 years
    Autoplay Policy Changes. Click me
  • DesTroy
    DesTroy about 6 years
    You can't possibly ask each and every user to go an change the settings .
  • Tuan Nguyen
    Tuan Nguyen almost 6 years
    It only use for developer to test Chrome autoplay policy behaviour locally. developers.google.com/web/updates/2017/09/…
  • nickiaconis
    nickiaconis almost 6 years
    Is 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
    nickiaconis almost 6 years
    I found that the command line flag --autoplay-policy=no-user-gesture-required is the programmatic way to achieve this setting.
  • koosa
    koosa over 5 years
    This only works for your browser, everybody else will still be affected
  • adripanico
    adripanico over 5 years
    Who is upvoting this answer? This is not superuser.com. A solution for your local machine cannot be an acceptable answer.
  • nikitahl
    nikitahl over 5 years
    Is there a way to enable audio right after the video starts playing? Removing the mute attribute or setting volume attribute doesn't help.
  • Kamil Kiełczewski
    Kamil Kiełczewski about 5 years
    On MacOs Chrome Version 74.0.3729.131 both snippets give black screen
  • Joe
    Joe about 5 years
    @KamilKiełczewski The video was showing a black screen because the src was invalid. I have updated the snippet src so the video auto plays.
  • Milan Švehla
    Milan Švehla over 4 years
    This 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
    Pedro Ferreira over 4 years
    Absolutely 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
    Pedro Ferreira over 4 years
    And, 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
    Ignacio Bustos over 4 years
    This 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
    tgordon18 about 4 years
    I had to do muted="true" instead
  • Marinpietri
    Marinpietri about 4 years
    That's it the answer. thks
  • Panagiss
    Panagiss almost 4 years
    it's better to set muted=true OR muted=false
  • Joe
    Joe almost 4 years
    @Panagiss I would say do muted="muted" or muted="true" Both work for me.
  • arao6
    arao6 almost 4 years
    Wow, 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
    loretoparisi almost 4 years
    This 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
    john Smith almost 4 years
    i guess you could be able to trigger gesture programmatically ? anybody?``
  • Kaiido
    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.g vid.play.then(vid.pause.bind(vid)), which is not really easier to read than the simple vid.play.then(()=>vid.pause()).
  • Andrews Gomes
    Andrews Gomes over 3 years
    Não funciona testei no chrome Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first
  • Sylvain Lesage
    Sylvain Lesage over 3 years
    Note 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
    Black over 3 years
    You can also just write muted works at least for me.
  • Bernesto
    Bernesto about 3 years
    This 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
    Gamer In The Game almost 3 years
    I have this problem with <audio> element, how can I solve it ?
  • TefoD
    TefoD almost 3 years
    Dito. Preventing errors and any policies was as well my goal. Any sound can wait till user interacts - just great!
  • almaruf
    almaruf over 2 years
    May 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
    akaravashkin over 2 years
    This is only correct answer! Thank you, helped me a lot.
  • Ajeet Eppakayala
    Ajeet Eppakayala about 2 years
    Could 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
    mergen about 2 years
    Doesn't work anymore in Chrome (tested against version 100.0.4896.127). Edit: mousemove works after performing a click once.