HTML5 Video muted but still playing HTML5 Video muted but still playing google-chrome google-chrome

HTML5 Video muted but still playing


In Angular case, one can try [muted]="'muted'", It is working for me.

<video id="video" style="width:100%; height:100%" autoplay [muted]="'muted'" loop>  <source src="./../../assets/video/model-video.mp4" type="video/mp4"></video>


I'm not entirely sure as to why the muted attribute is malfunctioning when defined within the video tag. However, this is what you can do :

Firstly, remove the muted="muted" attribute from the video tag. Keep it simply as :

<video id="video" width="640px" height="350px" autoplay="autoplay" loop="loop" controls="controls">    <source src="intouchables.f4v" type="video/mp4">    Your browser does not support the video tag.</video>

Now, define a function that on loading of the page, mutes the video.

window.onload = function () {    var element = document.getElementById('video');    element.muted = "muted";}

I have verified this, and it works.


There are no real new answers in my answer - just trying to bring this question up to date and hope to avoid people wasting a whole day with this like I just did.

As far as I can tell (especially since this question is so old) that muted has never worked when the video is dynamically added to the page. And since muted doesn't work then muted autoplay won't work either.

I think what happens is that the browser makes certain decisions on page load, and for some super odd reason, a video later to the page added will NOT mute even if it has muted property. This I believe is a bug in Chrome, not occurring for me in Safari - but it looks like we're stuck with it for now.

Google's blog entry on autoplay/mute is only a year old, and provides the following insight:

Chrome's autoplay policies are simple:

  • Muted autoplay is always allowed.
  • Autoplay with sound is allowed if:
    • User has interacted with the domain (click, tap, etc.).
    • On the desktop, the user's Media Engagement Index threshold has been crossed, meaning the user has previously played video with sound.
    • On mobile, the user has added the site to his or her home screen.
  • Top frames can delegate autoplay permission to their iframes to allow autoplay with sound.

There's just one major thing missing!

  • The 'muted' HTML attribute only takes effect when the video is present in the HTML at initial load. This also applies to 'autoplay muted' videos.

So what is the impact of this:

  • If a video with no sound is played programmatically it must be muted first. Therefore if a dynamic video is added to the page you must explicitly set video.muted = true after it is added to the DOM (or right before you play it).
  • If you try to execute video.play() programmatically (eg. when someone scrolls down past a muted video and you want it to play) then the video must be muted first.

I ran into this in Angular and spent way too much time assuming it was related to the fact I was using a template, or something Angular related.

I made a test app on StackBlitz. You will need to uncomment the line // video.muted = true to get it to work properly.

https://stackblitz.com/edit/angular-ze4t9y

The other important things to realize are:

  • Even if a video doesn't actually HAVE sound it must be muted. Test with the 'bunny' video if you need to.
  • The newer 'media engagement' rules outlined in the blog can confuse the heck out of you when testing a page because you will have interacted with the page. What you must do is close the browser, or open a new window in incognito mode - in order to reset this engagement rule (see blog entry).

The error you'll see in the browser if you try to play a non muted video when the user hasn't 'engaged' with the page first is shown below. If you aren't seeing this message for a non muted video then Chrome may have allowed the video to play because you interacted with the page.

enter image description here

And finally, if you are using Angular (where everything is dynamically added), the following works to mute the video:

 @ViewChild('bunnyVideo', { read: ElementRef }) bunnyVideo: ElementRef;

Then when you want to play it:

 const video: HTMLVideoElement = this.bunnyVideo.nativeElement; // explicitly mute it... video.muted = true; // ...before attempting to play video.play().catch((err) => {    alert('video error ' + err); });