UNPKG

hexa-viewer-communicator

Version:

A simple API for <hexa-viewer>

114 lines (103 loc) 3.6 kB
export class ImageToVideo { private cStream: MediaStream; private recorder: MediaRecorder; private chunks: Array<Blob>; private wrap: HTMLDivElement; private canvas: HTMLCanvasElement; private ctx: CanvasRenderingContext2D; private images: Array<string>; private frame: number; private resolve: Function; private FPS: number; private _codecs: string; constructor(images: Array<string>) { this._codecs = 'h264'; this.images = images; this.chunks = []; this.FPS = this.images.length / 15; this.wrap = document.createElement("div"); this.wrap.style.cssText = ` position: absolute; top: 0; left: 0; overflow: hidden; opacity: 0.01; z-index: -9999999; max-width: 100%; `; this.canvas = document.createElement("canvas"); this.wrap.appendChild(this.canvas); } get codecs() { return this._codecs; } set codecs(value: string) { this._codecs = value; } getVideo() { return new Promise((resolve: any, reject: any) => { this.resolve = resolve; document.body.appendChild(this.wrap); this.frame = 0; this.ctx = this.canvas.getContext("2d", { alpha: true }); const img = new Image(); img.onload = () => { this.canvas.width = img.naturalWidth; this.canvas.height = img.naturalHeight; this.start(); this.anim(); }; img.src = this.images[0]; }); } setTimeout(ms: number) { return new Promise((resolve: any, reject: any) => { setTimeout(() => { resolve(); }, ms); }); } anim() { const img = new Image(); img.onload = async () => { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.drawImage(img, 0, 0); if (++this.frame < this.images.length) { await this.setTimeout(1000 / this.FPS); requestAnimationFrame(this.anim.bind(this)); } else this.stopRecording(); }; img.src = this.images[this.frame]; } start() { // set the framerate to 30FPS this.cStream = this.canvas.captureStream(30); // this.cStream = this.canvas.captureStream(this.images.length / 30); // create a recorder fed with our canvas' stream const options = { // mimeType: 'video/webm', // mimeType: "video/webm;codecs=h264", mimeType: `video/webm;codecs=${this.codecs}`, // mimeType: 'video/webm;codecs="vp9, av1"', } as MediaRecorderOptions; this.recorder = new MediaRecorder(this.cStream, options); // start it this.recorder.start(); // save the chunks this.recorder.ondataavailable = this.saveChunks.bind(this); this.recorder.onstop = this.exportStream.bind(this); } saveChunks(e: BlobEvent) { this.chunks.push(e.data); } stopRecording() { this.recorder.stop(); } exportStream(e: Event) { // combine all our chunks in one blob // var blob = new Blob(this.chunks, { type: this.recorder.mimeType }); var blob = new Blob(this.chunks, { type: 'video/webm' }); this.resolve(blob); this.wrap.remove(); } }