#!/usr/local/bin/node global.path = require('path'); global.fs = require('fs'); global.zlib = require('zlib'); global.os = require('os'); global.child_process = require('child_process'); global.uuid = require('uuid')['v4']; global.version = "1.0"; global.argv = process.argv; argv.shift(); argv.shift(); console.log("Equestria Media Codec"); console.log(" (c) Copyright, Equestria.dev"); console.log("Eqmc Encoder"); console.log(" (c) Copyright, Equestria.dev"); console.log("version " + version); console.log(""); try { child_process.execSync("ffmpeg -version"); child_process.execSync("ffprobe -version"); child_process.execSync("ffplay -version"); } catch (e) { console.error("Unable to start the Eqmc Encoder:\n ffmpeg was not found or is incomplete"); process.exit(2); } if (argv.length < 1) { console.error("Unable to start the Eqmc Encoder:\n No output file has been specified"); process.exit(2); } global.output = argv[0].trim(); global.dir = path.dirname(output); global.file = path.basename(output); if (!output.endsWith(".eqmc")) { console.warn("warning: specified output (\"" + output + "\") does not contain extension, using \"" + output + ".eqmc\" instead."); file = file + ".eqmc"; output = output + ".eqmc"; } if (!fs.existsSync(dir)) { console.error("Unable to encode \"" + file + "\":\n \"" + dir + "\": no such file or directory"); process.exit(2); } if (fs.existsSync(output)) { console.error("Unable to encode \"" + file + "\":\n \"" + output + "\": file exists"); process.exit(2); } if (argv.length < 2) { console.error("Unable to encode \"" + file + "\":\n No input stream found"); process.exit(2); } global.inputs = argv; inputs.shift(); global.valid_inputs = []; global.out = { _eqmc: true, files: [] }; for (let input of inputs) { if (!fs.existsSync(input)) { console.warn("warning: specified input (\"" + input + "\") cannot be used: no such file or directory."); continue; } try { fs.readFileSync(input); } catch (e) { console.warn("warning: specified input (\"" + input + "\") cannot be used: file is unreadable."); continue; } let probe = JSON.parse(child_process.execFileSync("ffprobe", [ "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", input]).toString()); let streams = probe.streams.filter(i => i['codec_type'] === "audio"); if (streams.length < 1) { console.warn("warning: specified input (\"" + input + "\") cannot be used: no audio streams found."); continue; } if (streams.length > 1) { console.warn("warning: specified input (\"" + input + "\") contains more than one audio stream, only the " + probe.streams[0]["codec_name"] + " stream will be used."); continue; } valid_inputs.push(input); } for (let input of valid_inputs) { let probe = JSON.parse(child_process.execFileSync("ffprobe", [ "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", input]).toString()); let streams = probe.streams.filter(i => i['codec_type'] === "audio"); let fileId = uuid(); console.log("\n" + input + ":"); console.log(" Duration: " + new Date(probe.format['duration'] * 1000).toISOString().substring(11, 19)); console.log(" Container Type: " + probe.format['format_long_name']); console.log(" Stream Type: " + streams[0]['codec_long_name']); console.log(" Eqmc File ID: " + fileId); console.log(""); try { if (fs.existsSync(os.tmpdir() + "/eqmc-encode-temp")) { fs.rmSync(os.tmpdir() + "/eqmc-encode-temp", { recursive: true }); } fs.mkdirSync(os.tmpdir() + "/eqmc-encode-temp", { recursive: true }); } catch (e) { console.error("Unable to encode \"" + file + "\":\n Cannot create temporary working directory"); process.exit(2); } let outFile = os.tmpdir() + "/eqmc-encode-temp/" + fileId + ".wav"; console.log("Encoding \"" + output + ":/" + fileId + "\"..."); try { child_process.execFileSync("ffmpeg", [ "-v", "quiet", "-i", input, outFile ]); if (!fs.existsSync(outFile)) { console.error("Unable to encode \"" + file + "\":\n Successfully encoded file " + fileId + ", but file does not exist"); process.exit(2); } } catch (e) { console.error("Unable to encode \"" + file + "\":\n Failed to encode file " + fileId); process.exit(2); } out.files.push({ _id: fileId, data: zlib.deflateRawSync(fs.readFileSync(outFile), { level: -1, strategy: 0, memLevel: 9 }).toString("base64"), tags: probe.format.tags }) try { fs.rmSync(os.tmpdir() + "/eqmc-encode-temp", { recursive: true }); } catch (e) { console.error("Unable to encode \"" + file + "\":\n Cannot clear temporary working directory"); process.exit(2); } } console.log("Writing to \"" + output + "\"..."); fs.writeFileSync(output, zlib.deflateRawSync(JSON.stringify(out), { level: -1, strategy: 0, memLevel: 9 })); console.log("Done!");