简体   繁体   中英

Capturing the first video frame

I found many article in stackoverflow talking about how to capture the first video image frame, but I don't see what I'm doing wrong on the code to make it not working. So if someone can help me, thanks a lot !

HTML code:

<ion-button expand="block" color="primary" (click)="onPickVideo()">
   <ion-icon name="videocam" slot="start"></ion-icon>
   <ion-label>Select video</ion-label>
 </ion-button>

  <input type="file" (change)="onFileChosen($event)" #filePicker/>

<div class="wrapper" *ngIf="flag">
  <video controls >
    <source [src]="videoDetail.dataString" type="video/mp4">
    unsupported video
  </video>
</div>

TS Code:

import { Component, ViewChild, ElementRef } from '@angular/core';

export interface VideoDetail {
  ... Some code ...
}

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})
export class HomePage {

  ... Some code ...

  onPickVideo() {
    this.filePickerRef.nativeElement.click();
  }


  onFileChosen(ev: Event) {
    const files: FileList = (ev.target as HTMLInputElement).files;

  ... Some code ...      

    this.videoMetadataReader(this.videoBuffer, this.videoDetail);

    this.convertToDataString(this.videoBuffer, this.videoDetail);
  }

  // Metadata video reader
  videoMetadataReader(buffer: File, detail: VideoDetail) {
    const fileReader = new FileReader();
    this.videoBuffer = files[0];   // get video file

    fileReader.onload = () => {
      const blob = new Blob([fileReader.result], {type});

      const url = (URL || webkitURL).createObjectURL(blob);
      const video = document.createElement('video');  // create video element

      video.preload = 'metadata';                     // preload setting
      video.addEventListener('loadedmetadata', () => {

       ... Some code ...

        // Get first frame
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const img = new Image();


        canvas.height = video.videoHeight;
        canvas.width = video.videoWidth;

        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);


        img.src = canvas.toDataURL();
        detail.videoFrame = img.src;

        console.log('img :', img.src);

      });
      video.src = url; // start video load
    };
    fileReader.readAsArrayBuffer(buffer);
  }

  // File to dataUrl
  convertToDataString(buffer: File, detail: VideoDetail) {
    const fileReader = new FileReader();
    fileReader.onload = () => {
      const dataString = fileReader.result.toString();
      detail.dataString = dataString;
      this.flag = true;
    };
    fileReader.readAsDataURL(buffer);
  }
}

When I see the img in console.log I get an image, but totally white, and it should not be white.

Edit to show screenshot: In red the video frame capture, white.

在此处输入图片说明

Thanks again for help :)

Edited to add app link download :

Download source code here

I've reproduced your problem: you should replace preload type from preload to auto and event loadedmetadata should be changed to loadeddata or canplay .

BTW, I've used function below to convert blob to dataUri (can be changed to async or promises):

function blobToDataURL(blob, callback) {
  var a = new FileReader();
  a.onload = function(e) {callback(e.target.result);}
  a.readAsDataURL(blob);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM