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
Click the arrow next to export video at the top right corner of the Studio and select export as image. Use the slider that appears below the video to select the exact frame you want to download. You can also use the left and right arrows on your keyboard for more precision.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With