捕获第一个视频帧

时间:2020-01-13 10:54:13

标签: javascript html typescript ionic-framework ionic4

我在stackoverflow上发现了许多有关如何捕获第一个视频图像帧的文章,但是我看不出我在代码上做错了什么,以使其无法正常工作。因此,如果有人可以帮助我,非常感谢!

HTML代码:

<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代码:

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);
  }
}

当我在console.log中看到img时,我得到了一张图像,但是图像完全是白色的,并且应该不是白色的。

编辑以显示屏幕截图:视频帧捕获为红色,白色。

enter image description here

再次感谢您的帮助:)

已编辑以添加应用程序链接下载:

Download source code here

1 个答案:

答案 0 :(得分:2)

我已经重现了您的问题:您应该将预加载类型从preload替换为auto,并将事件loadedmetadata更改为loadeddatacanplay

顺便说一句,我已经使用下面的函数将blob转换为dataUri(可以更改为async或promises):

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