CodeAssasins
CodeAssasins

Reputation: 237

Get video element in ts file

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

Answers (1)

Jscti
Jscti

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 fpathis 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 *ngIfevaluates 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

Related Questions