Reputation: 237
I'm new to Ionic and working on Ionic 4. I want to get frame thumbnail from video src. For that I have to get video element in my .ts file. I tried using ViewChild as shown in this link. But when I run it in browser, I am getting this error TypeError: Cannot read property 'addEventListener' of undefined
. Is there anything which I'm missing? I got the element of Canvas also in same way and I think its working. But its not working for video tag.
export class UploadvidPage implements OnInit {
@ViewChild('myVideo') myVideo: ElementRef;
@ViewChild('myCanvas') myCanvas: ElementRef;
public isAndroid: boolean;
public imageUrl: any;
public fpath;
public video: any;
public canvas: any;
public context: CanvasRenderingContext2D;
ngAfterViewInit(): void {
this.video = this.myVideo.nativeElement;
this.canvas = this.myCanvas.nativeElement;
this.context =(<HTMLCanvasElement>this.canvas).getContext('2d');
}
handleFileSelect(evt){
let files = evt.target.files;
let file = files[0]
var binaryData = [];
binaryData.push(file);
this.fpath = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(new Blob(binaryData, {type: "application/zip"})));
var w,h,ratio;
//below code for setting snap of video into canvas
this.video.addEventListener('loadedmetadata', function() {
console.log('Got into video.addEventListener()');
ratio = this.video.videoWidth/this.video.videoHeight;
w = this.video.videoWidth-100;
h = w/ratio,10;
this.video.width = w;
this.canvas.height = h;
snap();
},false);
function snap() {
console.log('Got into snap()');
this.context.fillRect(0,0,w,h);
this.context.drawImage(this.video,0,0,w,h);
}
}
}
<input id="file-input" type="file" accept="video/*" (change)="handleFileSelect($event)">
<video *ngIf="fpath" id="myVideo" #myVideo controls>
<source [src]="fpath" id="source">
</video>
<canvas #myCanvas width="640" height="480"></canvas>
Upvotes: 1
Views: 1248
Reputation: 14440
You need to refactor your code. Because, in the code you posted, at view init (ViewChild
+ ngAfterViewInit
) your video doesn't exists yet because of the *ngIf="fpath"
(where fpath
is populated only on user selection, so in handleFileSelect
and not at view init).
Multiple solutions :
remove the *ngIf (prefer maybe be hiding it?). That way the ViewChild
+ ngAfterViewInit
will work perfectly
Dynamically retrieve the video template reference as soon as the *ngIf
evaluates to true (and let angular execute it before trying to use it). The following code will trigger the setter each time it resolves to true :
@ViewChild('myVideo') set content(content: ElementRef) {
this.myVideo = content;
}
+
Delay your addEventListener
: for example with a setTimeout
, to be sure that angular had time to init your myVideo
Upvotes: 1