diff options
author | Minteck <contact@minteck.org> | 2022-06-14 12:27:20 +0200 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2022-06-14 12:27:20 +0200 |
commit | a6eabecc147b17aae29c9dcfe2bfded153a0f548 (patch) | |
tree | e9d9c7d9aa2b7ee1828340f5a32a6e626e9a1aa2 /elac-encode | |
parent | ecb92e72778bb12b8875145650610617624c6530 (diff) | |
download | elac-a6eabecc147b17aae29c9dcfe2bfded153a0f548.tar.gz elac-a6eabecc147b17aae29c9dcfe2bfded153a0f548.tar.bz2 elac-a6eabecc147b17aae29c9dcfe2bfded153a0f548.zip |
Update
Diffstat (limited to 'elac-encode')
-rwxr-xr-x | elac-encode | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/elac-encode b/elac-encode new file mode 100755 index 0000000..63f2cf5 --- /dev/null +++ b/elac-encode @@ -0,0 +1,163 @@ +#!/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.1"; + +global.argv = process.argv; +argv.shift(); argv.shift(); + +console.log("Equestria Lossless Audio Codec"); +console.log(" (c) Copyright, Equestria.dev"); +console.log("ELAC 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 ELAC Encoder:\n ffmpeg was not found or is incomplete"); + process.exit(2); +} + +if (argv.length < 1) { + console.error("Unable to start the ELAC 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(".elac")) { + console.warn("warning: specified output (\"" + output + "\") does not contain extension, using \"" + output + ".elac\" instead."); + file = file + ".elac"; + output = output + ".elac"; +} + +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(); + + let lossless = false; + let outFile = os.tmpdir() + "/elac-encode-temp/" + fileId + ".opus"; + + if (streams[0]['codec_name'].includes("pcm") || streams[0]['codec_name'].includes("flac") || streams[0]['codec_name'].includes("alac") || streams[0]['codec_name'].includes("dts")) { + lossless = true; + outFile = os.tmpdir() + "/elac-encode-temp/" + fileId + ".flac"; + } + + 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(" ELAC Stream ID: " + fileId); + console.log(" Lossless Mode: " + (lossless ? "yes" : "no") + " (" + (lossless ? "ELAC Physical Lossless" : "ELAC Emulated Lossless") + ")"); + console.log(""); + + try { + if (fs.existsSync(os.tmpdir() + "/elac-encode-temp")) { + fs.rmSync(os.tmpdir() + "/elac-encode-temp", { recursive: true }); + } + fs.mkdirSync(os.tmpdir() + "/elac-encode-temp", { recursive: true }); + } catch (e) { + console.error("Unable to encode \"" + file + "\":\n Cannot create temporary working directory"); + process.exit(2); + } + + console.log("Encoding \"" + output + ":/" + fileId + "\"..."); + try { + child_process.execFileSync("ffmpeg", [ "-v", "quiet", "-i", input, "-map_metadata", "-1", 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, + lossless, + data: zlib.deflateSync(fs.readFileSync(outFile), { + level: -1, + strategy: 0, + memLevel: 9 + }).toString("base64"), + tags: probe.format.tags + }) + + try { + fs.rmSync(os.tmpdir() + "/elac-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.deflateSync(JSON.stringify(out), { + level: -1, + strategy: 0, + memLevel: 9 +})); +console.log("Done!");
\ No newline at end of file |