-
Notifications
You must be signed in to change notification settings - Fork 22
/
decode.js
137 lines (120 loc) · 4.47 KB
/
decode.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**
* @title Genshin Audio Extractor
* @description Extract .pck files from Genshin Impact
* @author Rie Takahashi
* When modifying or redistributing this project, do not modify this notice.
*/
const os = require("os");
const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");
const { StaticPool } = require("node-worker-threads-pool");
const { rmraf } = require("./helpers/rmraf");
const { pck2wem } = require("./helpers/pck2wem");
const { wem2wav } = require("./helpers/wem2wav");
const { wav2flac } = require("./helpers/wav2flac");
const { wav2mp3 } = require("./helpers/wav2mp3");
const arg = require("arg");
const cpuCount = os.cpus().length;
const main = async () => {
const args = arg({
// Types
"--input": String,
"--audio": arg.flag((val) => ["flac", "mp3", "flacandmp3"].includes(val) ? val : null),
"--verbose": arg.COUNT,
// Aliases
"-i": "--input",
"-a": "--audio",
"-v": "--verbose",
});
if (args['--verbose']) console.log('Verbose logging enabled');
const pckFiles = fs
.readdirSync(path.resolve(args['--input']))
.filter((f) => f.toLowerCase().endsWith(".pck"));
console.info(`Found ${pckFiles.length} pck files`);
if (args['--verbose']) console.log('Input: ' + args['--input'], 'Audio: ' + args['--audio']);
const pck2wemPool = new StaticPool({ size: cpuCount, task: pck2wem });
const wem2wavPool = new StaticPool({ size: cpuCount, task: wem2wav });
const wav2flacPool = new StaticPool({ size: cpuCount, task: wav2flac });
const wav2mp3Pool = new StaticPool({ size: cpuCount, task: wav2mp3 });
await Promise.all(
pckFiles
.map((file) => ({ filename: file, path: path.join(args['--input'], file) }))
.map(async (pckFile) => {
const dirName = pckFile.filename.substr(0, pckFile.filename.lastIndexOf('.'))
const processingDir = path.join(".", "processing", dirName);
await mkdirp(processingDir);
if (args['--verbose']) console.log('Processing: ' + pckFile.path);
await pck2wemPool.exec({ pckFile: pckFile.path, processingDir });
if (args['--verbose']) console.log('Finished: ' + pckFile.path);
const subWavOutputDir = path.join(".", "output", "WAV", dirName);
const subFlacOutputDir = path.join(".", "output", "FLAC", dirName);
const subMp3OutputDir = path.join(".", "output", "MP3", dirName);
await mkdirp(subWavOutputDir);
if (args['--audio'] === "flac" || args['--audio'] === "flacandmp3") {
await mkdirp(subFlacOutputDir);
}
if (args['--audio'] === "mp3" || args['--audio'] === "flacandmp3") {
await mkdirp(subMp3OutputDir);
}
const createdFiles = fs.readdirSync(processingDir);
await Promise.all(
createdFiles.map(async (createdFile) => {
await wem2wavPool.exec({
outputDir: subWavOutputDir,
createdFile,
processingDir,
});
})
);
switch (args['--audio']) {
case "flac":
await Promise.all(
createdFiles.map(async (createdFile) => {
await wav2flacPool.exec({
inputDir: subWavOutputDir,
outputDir: subFlacOutputDir,
createdFile,
});
})
);
break;
case "mp3":
await Promise.all(
createdFiles.map(async (createdFile) => {
await wav2mp3Pool.exec({
inputDir: subWavOutputDir,
outputDir: subMp3OutputDir,
createdFile,
});
})
);
break;
case "flacandmp3":
await Promise.all([
...createdFiles.map(async (createdFile) => {
await wav2flacPool.exec({
inputDir: subWavOutputDir,
outputDir: subFlacOutputDir,
createdFile,
});
}),
...createdFiles.map(async (createdFile) => {
await wav2mp3Pool.exec({
inputDir: subWavOutputDir,
outputDir: subMp3OutputDir,
createdFile,
});
}),
]);
break;
default:
break;
}
})
);
if (args['--verbose']) console.log('Removing processing folder');
await rmraf(path.join(".", "processing"));
process.exit();
};
main();