HTML5 video doesn't autoplay (even while muted) in Chrome 67 using Angular

14,387

Solution 1

Solution to Angular 2+ of cases in which automatic reproduction is needed silent and does not work.

  1. Autoplay is prevented, until the user performs an action on the screen. Chrome's autoplay policies will change in April of 2018. [https://developers.google.com/web/updates/2017/09/autoplay-policy-changes]
  2. Autoplay works when the "mute" attribute is selected.
  3. For this case, in which we want to use the attribute "mute" and it does not work, the problem is Angular.

The same thing happened to me and after hours of searching. And I found the following. - [https://stackoverflow.com/a/50686550/10435550][2]

onloadedmetadata="this.muted = true"

This is the key. Angular can not translate the attibute "mute" correctly. For this reason you have to use the "onloadedmetadata".

Conclusion

Tested and running with angular 5.2 in Chrome 69 and IE 11.

<video onloadedmetadata="this.muted=true" autoplay>
    <source src="myVideo.mp4" type="video/mp4" />
</video>

Solution 2

Using Angular 6.
I wanted a muted autoplay. None of the previous worked for me, this one did:

oncanplay="this.play()"

Hope it helps somebody.

Solution 3

I needed to use both onloadedmetadata and oncanplay to fix in angular 6

<video loop muted autoplay oncanplay="this.play()" onloadedmetadata="this.muted = true">
    <source src="video.mp4" type="video/mp4">
</video>

Solution 4

Instead of using the HTML attribute autoplay & muted. You need to use the Angular attributes [autoplay]="true" & [muted]="true"

Solution 5

Thanks to bigless' linking this SO post I solved the problem.

MY implementation of the solution from the link looks like this:

HTML

<div class="video-chrome-fix" [innerHTML]="videoTag"></div>

TypeScript

import {Component} from '@angular/core';
import {DomSanitizer} from "@angular/platform-browser";

@Component({
  selector: 'st-home',
  templateUrl: './home-page.component.html',
  styleUrls: ['./home-page.component.css']
})
export class HomePageComponent {

  videoTag;

  constructor(private sanitizer: DomSanitizer) {
    this.videoTag = this.getVideoTag();
  }

  private getVideoTag() {
    return this.sanitizer.bypassSecurityTrustHtml(
        `<video class="landing-page-video noselect" muted loop autoplay playsinline disableRemotePlayback>
            <source src="assets/images/landing-page-video-2.mp4" type="video/mp4">
            Your browser does not support HTML5 video.
        </video>`
    );
  }
}

NOTE: I had to move the class landing-page-video into the global styles.css file, since angular does not append the component specific prefix (ie. it won't apply the styling if it is placed in the component-specific css file)

Share:
14,387
Simon K
Author by

Simon K

Updated on June 06, 2022

Comments

  • Simon K
    Simon K almost 2 years

    I know several posts have similar issues, but none of the ones I have looked at have the specific issue I'm experiencing.

    The problem is, I have a HTML5 video which won't autoplay, even though it is muted. Specifically, it doesn't work in Chrome. It works completely fine in Safari and Firefox.

    The code snippet looks as such:

    <video class="landing-page-video" poster="assets/images/video-poster.jpg" loop muted playsinline preload="metadata" disableRemotePlayback>
        <source src="assets/images/landing-page-video-2.mp4" type="video/mp4">
        Your browser does not support video.
    </video>
    

    The code snippet is from this website and it is built with Angular. I've removed attributes that are only related to Angular in the copied snippet for clarity.

    I have tried several combinations of what is suggested various places online, as well as carefully reading the documentation for the newer versions of Chrome that affect the autoplay feature. I am, however, at a loss, with nothing seeming to work.

    Supposedly, the policy change should only affect autoplay for videos with audio, but it still seems to block autoplay for this muted video.

    One weird behavior that I have noticed is, that sometimes the video will start playing if I open the chrome inspector tool and close it again. Not always, though.

    I also tried triggering the play() directly through JavaScript, but this of course won't work since the user didn't initiate it through a click.

    Could this be a bug with Chrome or is it on my end? Any help is appreciated!


    EDIT: Still not working. I have tried the following, with no result:

    • Using the http://techslides.com/demos/sample-videos/small.mp4 video as source instead.
    • Adding autoplay attribute.
    • Replacing the whole <video> element with the one from the suggested jsfiddle.

    When I enable controls, the audio button shows as grayed out "sound on" version, might be due to my video having no audiotrack. However, when using the demo video, it still shows the audio button with "sound on" in spite of the muted attribute being set.


    EDIT 2: Added code for the Angular component which contains the video element:

    HTML:

    <video class="landing-page-video noselect"  poster="assets/images/video-poster.jpg" *showItSizes="{min:900}" muted loop autoplay disableRemotePlayback>
        <source src="assets/images/landing-page-video-2.mp4" type="video/mp4">
        Your browser does not support video.
    </video>
    
    <div class="landing-page-video-overlay noselect" *showItSizes="{min:900}" [ngStyle]="{'height': videoHeight + 'px'}">
        <st-svg-logo class="video-overlay-logo"></st-svg-logo>
    </div>
    <div class="noselect" *showItSizes="{max:899}" style="position: relative; top: 0; height: 100vh;">
        <img src="assets/images/landing_pic_mobile_3.jpg" alt="Student Talks in Space" class="landing-page-video"
             style="height: 100vh;">
        <img class="video-overlay-logo" src="assets/images/student-talks-header.png"/>
        <img src="assets/images/landing_pic_mobile_bottom.png" class="bottom-transition-glitch" alt="">
    </div>
    
    
    <div class="st-container">
        <st-events-list class="full-width event-list" *showItSizes="{max:899}"></st-events-list>
        <h1>HOW IT WORKS</h1>
        <st-what-is class="st-row"></st-what-is>
        <st-world-map class="full-width" *showItSizes="{min:899}"></st-world-map>
        <st-counters #counters class="full-width" stInView (cameInView)="counters.countUp()"></st-counters>
        <st-events-list class="full-width" *showItSizes="{min:900}"></st-events-list>
        <br><br>
        <st-video class="st-row"></st-video>
        <br><br>
        <st-partners></st-partners>
        <br><br>
    </div>
    

    CSS:

    .landing-page-video, .landing-page-video-overlay {
      position: relative;
      width: 100vw;
      max-width:100%;
      top: 0;
      z-index: -100;
    }
    
    .landing-page-video-overlay {
      height: 56.25vw;
      position: absolute;
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 100;
    }
    
    @media screen and (max-width: 899px) {
      .video-overlay-logo {
        position: absolute;
        top: 50vh;
        right: 21%;
        width: 100vw;
        animation: fade-in 1s;
        z-index: 160;
      }
    
    }
    

    TypeScript:

    import {Component, OnInit} from '@angular/core';
    
    @Component({
      selector: 'st-home',
      templateUrl: './home-page.component.html',
      styleUrls: ['./home-page.component.css']
    })
    export class HomePageComponent implements OnInit {
      constructor() {}
      ngOnInit() {}
    }