UNPKG

@ibaraki-douji/anime4k-gif

Version:

Upscale GIFs using Anime4kCPP

76 lines (65 loc) 2.55 kB
import Anime4k = require('@ibaraki-douji/anime4k') import { Options } from '@ibaraki-douji/anime4k/lib/types'; import path = require("path"); import { tmpdir } from "os"; import { mkdirSync, writeFileSync } from 'fs'; import { spawn, spawnSync } from 'child_process'; export = class Waifu2XGIF { public readonly inputPath: string; public readonly outputPath: string; public readonly up: any; public endBuffer: Buffer; public end = false; constructor (inp: string | Buffer, out: string, options: Options = {}) { if (typeof inp == "string") this.inputPath = path.resolve(inp); else { this.inputPath = path.resolve(tmpdir(), generate(50) + ".gif"); writeFileSync(this.inputPath, inp as Buffer); } if (options.outputAsBuffer) { this.outputPath = path.resolve(tmpdir(), generate(50) + ".gif"); } else { this.outputPath = path.resolve(out); } const vidTmp = path.resolve(tmpdir(), generate(50) + ".mp4"); const outTmp = path.resolve(tmpdir(), generate(50) + ".mp4"); spawnSync("ffmpeg", [ "-y", "-i", this.inputPath, "-pix_fmt", "yuv420p", "-c:v", "h264", "-movflags", "+faststart", "-filter:v", "crop='floor(in_w/2)*2:floor(in_h/2)*2'", vidTmp ]) this.up = Anime4k.upscale(vidTmp, outTmp, options); this.up.process.on("close", () => { this.endBuffer = this.up.endBuffer; spawnSync("ffmpeg", [ "-y", "-i", outTmp, "-c:v", "gif", "-pix_fmt", "bgra", this.outputPath ]) this.end = true; }) } public static upscale(inp: string | Buffer, out: string, options?: Options) { return new Waifu2XGIF(inp, out, options); } public static listGPUs() { return Anime4k.listGPUs(); } public finishedPromise() { return new Promise<void>(res => { let x = setInterval(() => { if (this.end) { clearInterval(x); res(); } }, 100); }); } } const generate=(length)=>{const alphabet="AZERTYUIOPQSDFGHJKLMWXCVBNazertyuiopqsdfghjklmwxcvbn123456789";let end="";for(let i=0;i<length;i++)end+=alphabet[Math.floor(Math.random()*alphabet.length)];return end}