Angular 16 and ViewChild and HTMLMediaElement
While working on an angular application where I had to develop the ability to manually control a video stream. Simple controls like, play, pause, and volume. “No problem!” I thought. HTML5 has these controls built-in and it will be super-simple to manipulate those methods with JS.
This simple task took me on a 3-day journey into the 7th circle of hell. I couldn’t get basic controls to work, couldn’t get any video helper library functional, and nothing I was doing seemed to be doing what it was supposed to! ARGH!
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
@Component({
selector: 'tvpreview',
templateUrl: './tvpreview.component.html',
styleUrls: ['./tvpreview.component.scss'],
})
export class TVPreviewComponent implements AfterViewInit {
@ViewChild("tvpreview") tvpreview: ElementRef;
streamLoaded = false;
streamStarted = false;
ngAfterViewInit() {
this.tvpreview.nativeElement.onloadeddata = (event) => {
console.log('Video data is loaded.');
this.streamLoaded = true;
};
this.tvpreview.nativeElement.onplaying = (event) => {
console.log('Video is no longer paused.');
this.streamStarted = true;
};
}
play() {
this.tvpreview.nativeElement.play();
}
pause() {
this.tvpreview.nativeElement.pause();
}
setMute() {
this.tvpreview.nativeElement.muted =
!this.tvpreview.nativeElement.muted;
}
}
Looks pretty simple, right?
In the above example, I was able to get play()
to work, and setMute()
to work, but pause()
would error out with (to summarize): nativeElement.pause is not a function
. What? So play() and muted are there, but pause isn’t? What in the world is happening???
After 3 days of banging my head against this problem and/or trying to find ways around it, I finally figured it out. The problem was this line:
@ViewChild("tvpreview") tvpreview: ElementRef;
Do you see it??
|
|
|
|
|
|
|
|
|
|
It’s the frickin’ QUOTES!!!!
I used this instead:
@ViewChild('tvpreview') tvpreview: ElementRef;
… and all is right with the world…
Hope this helps you not make the same mistake I did. =)