I am currently trying to implement an Angular directive that automatically mute and play an HTML5 video tag.
I am running this code in Angular 10. The error happens in all browsers that I tested.
Here is my code.
<video appVideoAutoplayMuted [autoplay]="true" preload="metadata" playsinline [controls]="false" [loop]="true" [muted]="true"
poster="../../../assets/video-mask-spot.png">
<source src="../../../assets/neon-smash-gameplay-trailer.mp4#t=0.5"
type="video/mp4">
<source src="../../../assets/neon-smash-gameplay-trailer.webm#t=0.5"
type="video/webm">
<source src="../../../assets/neon-smash-gameplay-trailer.ogv#t=0.5"
type="video/ogg">
Your browser does not support the video tag.
</video>
and the directive component looks like
import { Directive, ElementRef, OnInit} from '@angular/core';
@Directive({
selector: '[appVideoAutoplayMuted]'
})
export class VideoAutoplayMutedDirective implements OnInit {
constructor(public videoElement: ElementRef) {
}
ngOnInit(): void {
const video: HTMLVideoElement = this.videoElement.nativeElement;
video.muted = true;
video.play(); // play is not a function exception
}
}
When the code reaches video.play();
line it crashes giving me the next error.
ERROR TypeError: video.play is not a function
I debugged the code and the video const is not null and his type is HTMLVideoElement.
Intellisense is also working. I found in mdn that the function exists.
I found the solution. The problem was that the code was called on the server-side because I was using Angular Universal. I don't know why but seems like when HTMLVideoElement is in the server doesn't have play()
, load()
and other methods. I think that this methods are implemented by the browser.
I solved checking where is the code by running an if statement in the directive.
import {Directive, ElementRef, Inject, OnInit, PLATFORM_ID} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
@Directive({
selector: '[appVideoAutoplayMuted]'
})
export class VideoAutoplayMutedDirective implements OnInit {
constructor(public videoElement: ElementRef, @Inject(PLATFORM_ID) private platformId: any) {
}
ngOnInit(): void {
if (isPlatformBrowser(this.platformId)) { // here is the check
const video: HTMLVideoElement = this.videoElement.nativeElement;
video.muted = true;
video.play();
}
}
}
Please, feels free to expand this answer so we can get a better knowleadge of what is going on.