diff --git a/fileflows/scripts/03_Encode_AV1_QSV.js b/fileflows/scripts/03_Encode_AV1_QSV.js index a4da543..cdf8fa7 100644 --- a/fileflows/scripts/03_Encode_AV1_QSV.js +++ b/fileflows/scripts/03_Encode_AV1_QSV.js @@ -1,13 +1,33 @@ -function Script(CQ, Preset, SizePercent, BufsizeMultiplier, AQStrength, RcLookahead) +/** + * @name 03_Encode_AV1_NVENC + * @description AV1-Encode via NVIDIA NVENC fuer 4K-Remux Material. + * VBR mit CQ, maxrate = TargetPercent der Quelle, bufsize = MaxratePercent * BufsizeMultiplier. + * CUDA HW-Decode. HDR/DV-aware. Audio: EAC3-Kompatspur bei DTS, sonst copy. + * Subtitles 1:1. GROESSEN-SICHERHEITSNETZ: Output <= Original (Toleranz 5%). + * @author Sascha + Trulla + * @revision 2 + * @output Encode erfolgreich + * @output Skip / Fehler + * @param {int} TargetPercent Ziel-Bitrate als % der Quelle (z.B. 50 = halbe Bitrate) + * @param {int} MaxratePercent Peak-Cap als % der Quelle (z.B. 60) + * @param {int} BufsizeMultiplier bufsize = Maxrate * BufsizeMultiplier + * @param {int} RcLookahead NVENC rc-lookahead Frames + * @param {int} CQ Constant Quality (niedriger = besser, Default 24) + * @param {string} Preset NVENC Preset p1..p7 (Default p7 = langsamste/beste) + * @param {int} AQStrength Adaptive Quantization (Default 15) + */ +function Script(TargetPercent, MaxratePercent, BufsizeMultiplier, RcLookahead, CQ, Preset, AQStrength) { - CQ = CQ || 24; - Preset = Preset || 'p7'; - SizePercent = SizePercent || 60; - BufsizeMultiplier = BufsizeMultiplier || 2; - AQStrength = AQStrength || 15; - RcLookahead = RcLookahead || 64; + TargetPercent = TargetPercent || 50; + MaxratePercent = MaxratePercent || 60; + BufsizeMultiplier = BufsizeMultiplier || 2; + RcLookahead = RcLookahead || 40; + CQ = CQ || 24; + Preset = Preset || 'p7'; + AQStrength = AQStrength || 15; - let SizeFactor = SizePercent / 100; + let TargetFactor = TargetPercent / 100; + let MaxrateFactor = MaxratePercent / 100; // ───────────────────────────────────────────────────────────────────────── // Variables.vi.VideoInfo ist in dieser FileFlows-Version im ScriptNode LEER @@ -69,7 +89,8 @@ function Script(CQ, Preset, SizePercent, BufsizeMultiplier, AQStrength, RcLookah if (bitrateBps <= 0) { Logger.ELog('Bitrate nicht ermittelbar - Skip'); return 2; } let srcMbps = bitrateBps / 1000000; - let maxrateMbps = Math.round(srcMbps * SizeFactor * 10) / 10; + let targetMbps = Math.round(srcMbps * TargetFactor * 10) / 10; + let maxrateMbps = Math.round(srcMbps * MaxrateFactor * 10) / 10; let bufsizeMbps = Math.round(maxrateMbps * BufsizeMultiplier * 10) / 10; // HDR / Dolby Vision Detection @@ -85,8 +106,9 @@ function Script(CQ, Preset, SizePercent, BufsizeMultiplier, AQStrength, RcLookah let forceSDR = (isDV && dvProfile === 5); Logger.ILog('Quelle: ' + srcMbps.toFixed(1) + ' Mbit/s'); - Logger.ILog('Cap : maxrate=' + maxrateMbps + ' Mbit/s bufsize=' + bufsizeMbps + ' Mbit/s (<= ' + - SizePercent + '% der Quelle)'); + Logger.ILog('Target : ' + targetMbps + ' Mbit/s (' + TargetPercent + '%)'); + Logger.ILog('Cap : maxrate=' + maxrateMbps + ' Mbit/s bufsize=' + bufsizeMbps + ' Mbit/s (' + + MaxratePercent + '% der Quelle)'); Logger.ILog('Color : HDR10=' + isHDR10 + ' DV=' + isDV + ' Profile=' + dvProfile + ' forceSDR=' + forceSDR); // ── ffmpeg-Argumente @@ -101,7 +123,7 @@ function Script(CQ, Preset, SizePercent, BufsizeMultiplier, AQStrength, RcLookah '-pix_fmt', 'p010le', '-rc', 'vbr', '-cq', '' + CQ, - '-b:v', '0', + '-b:v', targetMbps + 'M', '-preset', Preset, '-tune', 'hq', '-multipass', 'fullres', @@ -198,6 +220,25 @@ function Script(CQ, Preset, SizePercent, BufsizeMultiplier, AQStrength, RcLookah return 2; } + // ── GROESSEN-SICHERHEITSNETZ ────────────────────────────────── + // Output darf nicht wesentlich groesser sein als die Quelle. + // Toleranz: 5% (fuer Audio-Stream-Unterschiede / Metadaten). + // Bei Ueberschreitung: Encode verwerfen, Original behalten, Warnung. + let origSizeStat = Flow.Execute({ command: '/usr/bin/stat', argumentList: ['-c', '%s', inputFile] }); + let origSize = parseInt((origSizeStat && origSizeStat.standardOutput) ? origSizeStat.standardOutput.trim() : '0', 10) || 0; + let newSizeStat = Flow.Execute({ command: '/usr/bin/stat', argumentList: ['-c', '%s', outFile] }); + let newSize = parseInt((newSizeStat && newSizeStat.standardOutput) ? newSizeStat.standardOutput.trim() : '0', 10) || 0; + + if (origSize > 0 && newSize > 0) { + let growthPct = ((newSize - origSize) / origSize) * 100; + Logger.ILog('Groesse: orig=' + origSize + ' bytes, output=' + newSize + ' bytes, growth=' + growthPct.toFixed(1) + '%'); + if (growthPct > 5) { + Logger.WLog('GROESSEN-WARNUNG: Output ' + growthPct.toFixed(1) + '% groesser als Quelle -> Encode verworfen, Original bleibt.'); + Flow.Execute({ command: '/bin/rm', argumentList: ['-f', outFile] }); + return 2; + } + } + Flow.SetWorkingFile(outFile); Logger.ILog('AV1 Encode erfolgreich -> ' + outFile); return 1;