Fix copy progress, remove v2.0.0, fix subtitle default naming, enforce strict no-upcoding on audio
Build / Lint & Test (push) Successful in 3m15s

This commit is contained in:
PickleRick committed 2026-09-30 17:26:19 +02:00
1 parent 7ee5a5bc48
commit 86448988ed
12 files changed
+470 -348

No files matched your search

@@ -1,4 +1,4 @@
'use strict';
'use strict';
/* eslint-disable no-param-reassign */
@@ -41,7 +41,20 @@ const getCodecWeight = (stream) => {
const getSourceBitrateKbps = (stream) => {
const br = parseInt(stream.bit_rate || '0', 10);
return br > 0 ? Math.round(br / 1000) : 0;
if (br > 0) return Math.round(br / 1000);
// Check tags for BPS (common in Matroska containers)
const tags = stream.tags || {};
const bpsEntry = Object.entries(tags).find(([key]) => {
const k = String(key).toLowerCase();
return k === 'bps' || k === 'bps-eng' || k === 'bps-ita' || k.startsWith('bps');
});
if (bpsEntry) {
const bps = parseInt(bpsEntry[1], 10);
if (bps > 0) return Math.round(bps / 1000);
}
return 0;
};
const calcOpusBitrate = (stream, isMovie, inputs) => {
@@ -52,18 +65,18 @@ const calcOpusBitrate = (stream, isMovie, inputs) => {
const serThreshold = parseInt(inputs.seriesMultiChannelThreshold || '384', 10);
if (ch <= 2) {
// Stereo: min(max, source) — no upcoding
// Stereo: min(max, source) — strict no upcoding
return srcKbps > 0 ? Math.min(stereoMax, srcKbps) : stereoMax;
}
// Multichannel
if (isMovie) {
return srcKbps > 0 ? Math.min(filmTarget, srcKbps) : filmTarget;
// Multichannel target cap
const maxTarget = isMovie ? filmTarget : serThreshold;
// Strict no upcoding: if source bitrate is known, never exceed source bitrate
if (srcKbps > 0) {
return Math.min(maxTarget, srcKbps);
}
// Series
// If bitrate is unknown (0), assume high-quality source -> use 384k
const effectiveKbps = srcKbps > 0 ? srcKbps : serThreshold;
return effectiveKbps >= serThreshold ? 384 : 256;
return maxTarget;
};
const details = () => ({
@@ -118,7 +131,8 @@ const plugin = async (args) => {
jobLog(`[audioSelectorClamping] Processing: ${filePath}\n`);
const isMovie = variables.isMovie === 'true';
jobLog(`[audioSelectorClamping] isMovie=${isMovie}\n`);
const isAnimation = variables.isAnimation === 'true';
jobLog(`[audioSelectorClamping] isMovie=${isMovie} isAnimation=${isAnimation}\n`);
const streams = (inputFileObj.ffProbeData && inputFileObj.ffProbeData.streams) || [];
const audioStreams = streams.filter((s) => s.codec_type === 'audio');