Compare commits
No commits in common. "master" and "dfb23823443fc9065b984f3a9ba4f2a9fbdc8219" have entirely different histories.
master
...
dfb2382344
@ -12,9 +12,6 @@ const FREQ = 48000;
|
||||
const FRAMERATE = parseFloat(
|
||||
(await $`mediainfo --Output="Video;%FrameRate%" ${video}`).stdout
|
||||
);
|
||||
const BITRATE = parseFloat(
|
||||
(await $`mediainfo --Inform="Video;%BitRate/String%" ${video}`).stdout
|
||||
);
|
||||
|
||||
const labels_contents = (await $`awk '{print $3, $4, $5}' < ${labels}`).stdout;
|
||||
|
||||
@ -75,20 +72,20 @@ current_piece.end = all_frames[all_frames.length - 1];
|
||||
|
||||
pieces.push(current_piece);
|
||||
|
||||
// this approach is using a filter, so it requires reencoding the entire video, but lets us be very precise:
|
||||
// const filter = pieces
|
||||
// .map(
|
||||
// ({ start, end }) =>
|
||||
// `between(t,${(start / FRAMERATE).toFixed(5)},${(end / FRAMERATE).toFixed(
|
||||
// 5
|
||||
// )})`
|
||||
// )
|
||||
// .join("+");
|
||||
// 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"}`;
|
||||
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 = [];
|
||||
@ -117,72 +114,3 @@ pieces.push(current_piece);
|
||||
// await $`ffmpeg -f concat -safe 0 -i /tmp/vdlist.txt -c copy -y ${
|
||||
// video + "final.mp4"
|
||||
// } `;
|
||||
|
||||
function range(n) {
|
||||
return [...Array(n).keys()];
|
||||
}
|
||||
|
||||
for (let piece of pieces) {
|
||||
console.log(piece);
|
||||
}
|
||||
|
||||
const ns = range(pieces.length);
|
||||
|
||||
const sample_rate = parseInt(
|
||||
(
|
||||
await $`ffprobe ${video} 2>&1 | grep 'Audio:' | grep --only-matching --extended-regexp '[0-9]+ Hz' | sed 's/ Hz//'`
|
||||
).stdout
|
||||
); // in Hz
|
||||
|
||||
const samples_per_frame = sample_rate / FRAMERATE;
|
||||
|
||||
function generateSplit(pieces, prefix = "") {
|
||||
return `[0] ${prefix}split=${pieces.length} ${ns
|
||||
.map((n) => `[copy${n}${prefix}]`)
|
||||
.join("")}`;
|
||||
}
|
||||
|
||||
function generateFilter(pieces, prefix = "") {
|
||||
return pieces
|
||||
.map(
|
||||
(piece, n) =>
|
||||
`[copy${n}${prefix}]${prefix}trim=start_frame=${piece.start}:end_frame=${piece.end},setpts=PTS-STARTPTS [copy${n}t${prefix}]`
|
||||
)
|
||||
.join("; ");
|
||||
}
|
||||
|
||||
function generateAudioFilter(pieces) {
|
||||
return pieces
|
||||
.map(
|
||||
(piece, n) =>
|
||||
`[copy${n}a]atrim=start_sample=${
|
||||
piece.start * samples_per_frame
|
||||
}:end_sample=${
|
||||
(piece.end + 1) * samples_per_frame
|
||||
},asetpts=PTS-STARTPTS [copy${n}ta]`
|
||||
)
|
||||
.join("; ");
|
||||
}
|
||||
|
||||
// version with audio, that doesn't work yet:
|
||||
// const filter = `${generateSplit(pieces)}; ${generateSplit(
|
||||
// pieces,
|
||||
// "a"
|
||||
// )}; ${generateFilter(pieces)}; ${generateAudioFilter(pieces)}; ${ns
|
||||
// .map((n) => `[copy${n}t]`)
|
||||
// .join("")} concat=n=${pieces.length} [out_video]; ${ns
|
||||
// .map((n) => `[copy${n}ta]`)
|
||||
// .join("")} concat=n=${pieces.length} [out_audio]`;
|
||||
|
||||
// video-only version
|
||||
const audio_filter = `${generateSplit(pieces, "a")}; ${generateAudioFilter(
|
||||
pieces
|
||||
)};`;
|
||||
|
||||
const filter = `${generateSplit(pieces)};
|
||||
${generateFilter(pieces)};
|
||||
${audio_filter}
|
||||
${ns.map((n) => `[copy${n}t][copy${n}ta]`).join(" ")}
|
||||
concat=n=${pieces.length}:v=1:a=1 [out_video] [out_audio]`;
|
||||
|
||||
await $`ffmpeg -i ${video} -b:v ${BITRATE}M -filter_complex ${filter} -map '[out_video]' -map '[out_audio]' ${`${video}.cut-complex.mp4`}`;
|
||||
|
Loading…
Reference in New Issue
Block a user