If I put a video tag with "autoplay" (see below) into the template of an Angular 2+ component with the goal of autoplaying on mobile:
<video muted autoplay>
<source src="path/to/video.mp4" type="video/mp4" />
</video>
Appending it to the body from within the component:
window.addEventListener('load', () => {
document.body.innerHTML += "<video autoplay muted loop>\n" +
" <source src=\"path/to/video.mp4\" type=\"video/mp4\" />\n" +
"</video>";
});
I don't think it's an issue of an invalid path to the video, since I'm able to manually click the "play" button.
According to here and here, autoplay on mobile should be allowed if (1) the video is muted, and (2) the video is "visible". I've read that "visible" in this context is more or less defined to mean "attached to DOM" and not "display: none" in at least a couple of places.
My best theory is that Angular 2+ is sticking the component in some kind of "Shadow DOM" (or similar) that's resulting in mobile Chrome not thinking that it's visible. I tried setting the component to encapsulation: ViewEncapsulation.None
to see if that made a difference, but same result.
Additionally, if I try to set an event listener against the "loaded" or "canplaythrough" events and manually call videoElement.play()
, then I get: DOMException: play() can only be initiated by a user gesture
. If I make the same function call in the devtools console (tethering to mobile device via USB), then it does play.
It seems that Angular is likely what's getting in my way. Is there any known Angular setting or workaround I can leverage to get a video to autoplay within an Angular 2+ component on Android Chrome? Thanks for any help.
(p.s.: there's like a million questions on S.O. and elsewhere about autoplaying video on mobile Chrome, but none of them seem to address the issue of doing it within an Angular component or similar)
I was searching for this issue a lot and I put the muted attribute like this:
[muted]="true"
rather than just muted
and now it works
<video [muted]="true" autoplay>
<source src="path/to/video.mp4" type="video/mp4" />
</video>
Chrome has a policy to not let videos autoplay if the user has not first interacted with the page however if its a muted video chrome allows it. The problem here is that for some reason muted value goes as false when you just put muted
in angular.
I needed to use both onloadedmetadata
and oncanplay
to fix in angular 6
<video id="bg-video" loop muted autoplay oncanplay="this.play()" onloadedmetadata="this.muted = true">
<source src="video.mp4" type="video/mp4">
</video>
Similar issue with Angular 6 and Chrome 70.
In fact, the muted attribute in the HTML seems to be ignored by Chrome when the video is added by Angular. The resulting DOM element has a 'muted' property set to 'false'. Not sure if it is an Angular or a Chrome bug.
You need to set it manually to true to make the autoplay work.
I ended up with a directive :
@Directive({selector: '[my-autoplay]' })
export class AutoplayVideoDirective implements OnInit {
constructor(public element: ElementRef) { }
public ngOnInit(): void {
let vid = this.element.nativeElement;
vid.muted = true;
vid.play();
}
}
and the HTML :
<video loop muted autoplay my-autoplay>
Had a similar issue with Chrome 66 (OSX High Sierra) not autoplaying a muted video in a Mat Dialog being opened by its parent on init. Solved it by adding *ngIf="true"
to the video element:
<video *ngIf="true" autoplay muted onloadedmetadata="this.muted = true" controls>
<source src="myVid.mp4" type="video/mp4">
<p>Your browser does not support the video element.</p>
</video>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With