我在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时,我得到了一张图像,但是图像完全是白色的,并且应该不是白色的。
编辑以显示屏幕截图:视频帧捕获为红色,白色。
再次感谢您的帮助:)
已编辑以添加应用程序链接下载:
答案 0 :(得分:2)
我已经重现了您的问题:您应该将预加载类型从preload
替换为auto
,并将事件loadedmetadata
更改为loadeddata
或canplay
。
顺便说一句,我已经使用下面的函数将blob转换为dataUri(可以更改为async或promises):
function blobToDataURL(blob, callback) {
var a = new FileReader();
a.onload = function(e) {callback(e.target.result);}
a.readAsDataURL(blob);
}