-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdoEverything.js
More file actions
332 lines (314 loc) · 11.9 KB
/
Copy pathdoEverything.js
File metadata and controls
332 lines (314 loc) · 11.9 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
const util = require("util");
const exec = util.promisify(require("child_process").exec);
const fs = require("fs");
const path = require("path");
const process = require("process");
const readline = require("readline");
let cropTries = 1;
const currentFolder = process.cwd();
// Modules
const { getVideoInfo } = require("./Modules/getVideoInfo.js");
const { createScreenshots } = require("./Modules/createScreenshots.js");
const { testCRF } = require("./Modules/testCRF.js");
const {
createScreenshotsMetadata,
} = require("./Modules/createScreenshotsMetadata.js");
const { jimpAnalysis } = require("./Modules/jimpAnalysis.js");
const {
cropHorizontally,
cropVertically,
} = require(`./Modules/cropFunction.js`);
const { encodeAudio } = require("./Modules/encodeAudio.js");
const { getTracksInfo } = require("./Modules/getTracksInfo.js");
const { extractTracks } = require("./Modules/extractTracks.js");
const { mergeEncoded } = require("./Modules/mergeEncoded.js");
const {
copyScreenshots,
getOSuri,
randomFrame,
randomFrameDistribution,
renameScreenshots,
} = require("./Modules/Utils.js");
const { dox264Tests } = require("./Modules/dox264Tests.js");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const askingTitle = () => {
return new Promise((resolve, reject) =>
rl.question(
"Enter Title of the track, if you dont input anything it will have the same\n",
async (title) => {
resolve(title);
}
)
);
};
const askingLanguage = () => {
return new Promise((resolve, reject) =>
rl.question(
"Enter language of the track, if you dont input anything it will have the sam\n",
async (language) => {
resolve(language);
}
)
);
};
const askingForVideo = () => {
return new Promise((resolve, reject) =>
rl.question(
"Enter the video Link (Only mkv videos will work) \nExample: c:\\users\\videos\\my video.mkv\n ",
async (videoLink) => {
const video = getOSuri(videoLink);
resolve(video);
}
)
);
};
const askingNumber = (msg, defaultNumber) => {
return new Promise((resolve, reject) =>
rl.question(msg, async (number) => {
if (number.match(/^\d+$/)) resolve(parseInt(number));
resolve(defaultNumber);
})
);
};
const askingConfirmation = (msg) => {
return new Promise((resolve, reject) =>
rl.question(msg, async (confirm) => {
if (confirm.match(/^y$/i)) resolve(true);
resolve(false);
})
);
};
const main = async () => {
try {
console.log("This will be the first test of doing everything to encode\n");
const video = await askingForVideo();
let vsSetting = `
import vapoursynth as vs
core = vs.get_core()
clip = core.ffms2.Source(${video})
`;
console.log("First we are looking for the crop settings\n");
const numberOfScreenshots = await askingNumber(
"Enter the number of Sceenshots you want for the crop test(it has to be an integer), if you use an invalid number or just press enter it will default to 15\n",
15
);
console.log(numberOfScreenshots, " Screenshots will be made\n");
const { numberOfFrames, sourceHeight, FPSNumber } = await getVideoInfo(
video
);
const fps = Math.round(FPSNumber);
const positions = randomFrameDistribution(
numberOfFrames,
numberOfScreenshots
);
const cropOutput = path.join(
currentFolder,
`Crop preview/Take number - ${cropTries}`
);
if (!fs.existsSync(cropOutput)) {
fs.mkdirSync(cropOutput, { recursive: true });
}
await createScreenshots({
video,
outputFolder: cropOutput,
name: "crop",
positions,
});
const folder = path.join(
currentFolder,
`Crop preview/Take number - ${cropTries}/screenshots`
);
const { removeTop, removeBottom } = await cropVertically(folder, "crop");
const { removeRight, removeLeft } = await cropHorizontally(folder, "crop");
console.log(
`the recomended crop setting is\n clip = core.std.Crop(clip, left=${removeLeft}, right=${removeRight},top = ${removeTop},bottom = ${removeBottom})\n`
);
console.log("Proccesing cropped previews with recomended settings");
const extraOptions = `clip = core.std.Crop(clip, left=${removeLeft}, right=${removeRight},top = ${removeTop},bottom = ${removeBottom})
`;
await createScreenshots({
video,
outputFolder: cropOutput,
name: "Cropped",
positions,
extraOptions,
});
console.log(
`You can see all screenshots at Crop preview/Take number - ${cropTries} with the suggested options\n`
);
const useSetting = await askingConfirmation(
"Do you want to use those Settings ? \nSend [Y] or [y] if you are\nSend other letter if you are not\n"
);
if (useSetting) {
vsSetting += extraOptions;
} else {
vsSetting +=
"clip = core.std.Crop(clip, left=number, right=number,top = number,bottom = number)\n";
console.log(
"Edit the settings on the vsSetting.py with this format\nclip = core.std.Crop(clip, left=number, right=number,top = number,bottom = number)\n all numbers most be odd numbers\nIf you know what you are doing you can also add filters\nDon't set up the .set_output, and make all the filters to equal to clip\n"
);
}
fs.writeFileSync("vsSetting.py", vsSetting);
console.log("Now is time to decide what x264 settings to use\n");
console.log("An analysis using the cropped screenshots will be done\n");
const folderOfSS = path.join(
currentFolder,
`Crop preview/Take number - ${cropTries}/screenshots`
);
const analysis = await jimpAnalysis(folderOfSS, "Cropped");
console.log(`Analysis result:\n treshhold = 5 \n${analysis}`);
const testX264Settings = await askingConfirmation(
"Given those results do you know what settings to use? \nSend [Y] or [y] if you do \nSend other input if you don't\n"
);
const x264SettingFormat = `bin\\x264 --demuxer y4m --output encoded.mkv - Add Your flags here`;
fs.writeFileSync(`x264-setting.txt`, x264SettingFormat);
const p2pTemplate = await askingConfirmation(
"Do you want to use p2p templated x264 settings y/n \n"
);
let isPtp = false;
let isAnime = false;
if (p2pTemplate) {
isPtp = true;
let p2pformat = "";
const animeQuestion = await askingConfirmation(
"Is the video an Anime? \n"
);
if (animeQuestion) {
isAnime = true;
p2pformat = `bin\\x264 --demuxer y4m --level 4.1 --b-adapt 2 --vbv-bufsize 78125 --vbv-maxrate 62500 --rc-lookahead 250 --me tesa --direct auto --subme 11 --trellis 2 --no-dct-decimate --no-fast-pskip --output encoded.mkv - --ref --min-keyint ${fps} --aq-mode 2 --aq-strength EDIT --deblock EDIT --qcomp EDIT --psy-rd EDIT --bframes 16`;
} else {
p2pformat = `bin\\x264 --demuxer y4m --level 4.1 --b-adapt 2 --vbv-bufsize 78125 --vbv-maxrate 62500 --rc-lookahead 250 --me tesa --direct auto --subme 11 --trellis 2 --no-dct-decimate --no-fast-pskip --output encoded.mkv - --ref --min-keyint ${fps} --aq-mode EDIT --aq-strength EDIT --qcomp EDIT --psy-rd EDIT --bframes 16`;
}
fs.writeFileSync(`x264-setting.txt`, p2pformat);
}
const areyousure = await askingConfirmation(
"Are you sure you want to do the tests ? [Y]es or [N]ot\n"
);
if (!testX264Settings && areyousure) {
await dox264Tests({
video,
extraOptions,
isAnime,
isPtp,
fps,
resolution: sourceHeight,
});
console.log(
`Edit x264-setting.txt with the settings you want to use dont change the demuxer or the input "-"\n`
);
}
let confifrmEdittedx264 = false;
do {
confifrmEdittedx264 = await askingConfirmation(
"Once you finished editing press [Y] or [y]"
);
} while (!confifrmEdittedx264);
console.log(
"Now is time to look for the CRF settings on the resolutions you want to encode on\n"
);
const Resolutions = [480, 576, 720, 1080];
const ref = [16, 12, 9, 4];
let crfValues = [0, 0, 0, 0];
let i = 0;
for (const resolution of Resolutions) {
const confirmation = await askingConfirmation(
`Do you want To encode on ${resolution}p, send [y] or [Y] to confirm, any other letter to not\n`
);
if (confirmation) {
const Every = await askingNumber(
"Enter the number frames to skip for cycle on the test script(it has to be an integer), if you use an invalid number or just press enter it will default to 3000\n",
3000
);
const Length = await askingNumber(
"Enter the number frames of each scene for the test script(it has to be an integer), if you use an invalid number or just press enter it will default to 50\n",
50
);
const Offset = await askingNumber(
"Enter the number of frames to offset from the start and end of the video those frames will be not taken for the test on the test script(it has to be an integer), if you use an invalid number or just press enter it will default to 10000\n",
10000
);
const crf = await testCRF({
video,
resolution,
Every,
Length,
Offset,
extraOptions,
});
crfValues[i] = crf;
}
i += 1;
}
console.log(
"Now that we finish all the test is time to start the encode\n"
);
const willYouChange = await askingConfirmation(
"If you want to encode on the ssame resolutions you ran the crf test press [y] or [Y] if not press another letter or key\n"
);
const vspipeLocation = path.join(currentFolder, `vsSetting.py`);
const x264SettingLocation = path.join(currentFolder, `x264-setting.txt`);
if (!willYouChange) {
let i = 0;
for (const resolution of Resolutions) {
const confirm = await askingConfirmation(
`Do you want to encode on ${resolution}\n Press [y] or [Y] if you do\n if you don't press another letter or key\n`
);
if (confirm) {
let vsPipe = fs.readFileSync(vspipeLocation, "utf8");
vsPipe += `
ratio = clip.width/clip.height
w = round(${resolution}*ratio/2)*2
clip = core.resize.Spline36(clip,width=w,height=${resolution})
clip.set_output()
`;
fs.writeFileSync(`vs${resolution}Setting.py`, vsPipe);
const x264SSetting = fs
.readFileSync(x264SettingLocation, "utf8")
.replace("encoded.mkv", `encoded${resolution}.mkv`)
.replace("--ref", `--ref ${ref[i]}`)
.trim();
console.log(` . . . Encdoding ${resolution}\n`);
const { stdout, stderr } = await exec(
`bin\\vspipe --y4m vs${resolution}Setting.py - | ${x264SSetting} --crf ${crfValues[i]} `
);
}
const x264log = stdout+stderr
fs.writeFileSync(`x264-${resolution}-log.txt`,x264log)
i += 1;
}
} else {
let i = 0;
for (const crf of crfValues) {
if (crf !== 0) {
const resolution = Resolutions[i];
let vsPipe = fs.readFileSync(vspipeLocation, "utf8");
vsPipe += `
ratio = clip.width/clip.height
w = round(${resolution}*ratio/2)*2
clip = core.resize.Spline36(clip,width=w,height=${resolution})
clip.set_output()
`;
fs.writeFileSync(`vs${resolution}Setting.py`, vsPipe);
const x264SSetting = fs
.readFileSync(x264SettingLocation, "utf8")
.replace("encoded.mkv", `encoded${resolution}.mkv`)
.replace("--ref", `--ref ${ref[i]}`)
.trim();
console.log(` . . . Encdoding ${resolution}\n`);
const {stdout,stderr} = await exec(
`vspipe --y4m vs${resolution}Setting.py - | ${x264SSetting} --crf ${crf} `
);
const x264log = stdout+stderr
fs.writeFileSync(`x264-${resolution}-log.txt`,x264log)
}
i += 1;
}
}
} catch (error) {
console.log(error);
}
};
main();