You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.6 KiB
JavaScript
117 lines
2.6 KiB
JavaScript
3 years ago
|
#!/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"
|
||
|
// } `;
|