const { Readable, PassThrough } = require("stream"); const { spawn } = require("child_process"); class FFMPEG { constructor(data) { this.data = data; // Can be Readable or Buffer this.isBuffer = data instanceof Buffer; } convert() { return new Promise((resolve, reject) => { const ffmpegArgs = [ "-i", "pipe:0", "-c:v", "libx264", "-profile:v", "high", "-level", "4.1", "-c:a", "aac", "-crf", "26", "-preset", "medium", "-movflags", "+frag_keyframe+empty_moov+default_base_moof", "-f", "mp4", "pipe:1", ]; const ff = spawn("ffmpeg", ffmpegArgs); const inputStream = this.isBuffer ? Readable.from(this.data) : this.data; inputStream.pipe(ff.stdin); const output = new PassThrough(); ff.stdout.pipe(output); let errData = ""; ff.stderr.on("data", (chunk) => (errData += chunk.toString())); ff.on("close", (code) => { if (code !== 0) { reject(new Error(`FFMPEG exited with code ${code}\n${errData}`)); } }); ff.on("error", reject); resolve(output); }); } } module.exports = FFMPEG;