Add newer, faster version

This commit is contained in:
Kuba Orlik 2021-09-18 14:17:40 +02:00
parent 9fd852a1cf
commit dfb2382344
2 changed files with 117 additions and 1 deletions

View File

@ -42,7 +42,7 @@ ffmpeg -i video.mp4 -vn -acodec copy audio.aac
3. Wyeksportuj wszystkie labelki do pliku tekstowego (export -> labels)
4. Uruchom `zx --quiet dziurkacz.mjs /ścieżka/do/pliku/video.mp4 /ścieżka/do/pliku/z/wyeskportowanymi/labelkami.txt`
4. Uruchom `zx --quiet dziurkacz-fast.mjs /ścieżka/do/pliku/video.mp4 /ścieżka/do/pliku/z/wyeskportowanymi/labelkami.txt`
Plik wynikowy znajdziesz w /tmp/dziurkacz/working.mp4

116
dziurkacz-fast.mjs Executable file
View File

@ -0,0 +1,116 @@
#!/usr/bin/zx
const { extname } = require("path");
const args = process.argv.slice(-2);
const video = args[0];
const labels = args[1];
const ext = extname(video);
const FREQ = 48000;
const FRAMERATE = parseFloat(
(await $`mediainfo --Output="Video;%FrameRate%" ${video}`).stdout
);
const labels_contents = (await $`awk '{print $3, $4, $5}' < ${labels}`).stdout;
const cuts = labels_contents
.split(os.EOL)
.slice(0, -1)
.map((e) =>
e
.split(" ")
.slice(1)
.map((x) => parseFloat(x))
)
.map(([samples, start]) => ({
duration: samples / FREQ,
start,
end: start + samples / FREQ,
}));
console.log(cuts);
let all_frames = [];
const frame_count = parseInt(
(await $`mediainfo --Output="Video;%FrameCount%" ${video}`).stdout
);
for (let i = 0; i < frame_count; i++) {
all_frames.push(i);
}
console.log(all_frames);
for (let cut of cuts) {
all_frames = [
...all_frames.slice(0, Math.round(cut.start * FRAMERATE)),
...all_frames.slice(Math.round(cut.end * FRAMERATE)),
];
}
console.log(all_frames);
const pieces = [];
let current_piece = { start: all_frames[0] };
let predicted_frame_number = 0;
// skipping the first one, as we're doing lookback
for (let i = 1; i < all_frames.length; i++) {
if (all_frames[i] != all_frames[i - 1] + 1) {
current_piece.end = all_frames[i - 1];
pieces.push(current_piece);
current_piece = { start: all_frames[i] };
}
}
current_piece.end = all_frames[all_frames.length - 1];
pieces.push(current_piece);
// discarding this as using a filter requires reencoding the entire video:
const filter = pieces
.map(
({ start, end }) =>
`between(t,${(start / FRAMERATE).toFixed(5)},${(end / FRAMERATE).toFixed(
5
)})`
)
.join("+");
await $`ffmpeg -i ${video} \
-vf ${`select='${filter}',setpts=N/FRAME_RATE/TB`} \
-af ${`aselect='${filter}',asetpts=N/SR/TB`} \
${video + ".cut.mp4"}`;
// let ffmpeg_args = [];
// const parts = [];
// for (let i in pieces) {
// const piece = pieces[i];
// const output_filename = video + "-" + i + ".mp4";
// ffmpeg_args = [
// ...ffmpeg_args,
// "-ss",
// (piece.start / FRAMERATE).toFixed(5),
// "-t",
// ((piece.end - piece.start) / FRAMERATE).toFixed(5),
// "-c",
// "copy",
// output_filename,
// ];
// parts.push(output_filename);
// }
// console.log(ffmpeg_args);
// await $`ffmpeg -i ${video} ${ffmpeg_args}`;
// await $`echo ${parts.map((s) => `file ${s}`).join("\n")} > /tmp/vdlist.txt`;
// await $`ffmpeg -f concat -safe 0 -i /tmp/vdlist.txt -c copy -y ${
// video + "final.mp4"
// } `;