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