chore: add 04b_Add_EAC3_if_DTS.js from live FileFlows export
This commit is contained in:
parent
58f72719e1
commit
b29cc860bb
1 changed files with 113 additions and 0 deletions
113
fileflows/scripts/04b_Add_EAC3_if_DTS.js
Normal file
113
fileflows/scripts/04b_Add_EAC3_if_DTS.js
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* @name 04b_Add_EAC3_if_DTS
|
||||||
|
* @description Haengt eine EAC3-Kompatibilitaetsspur an, OHNE das Video neu zu encoden
|
||||||
|
* (Video = copy). Trigger: die beste deutsche Tonspur ist eine DTS-Variante
|
||||||
|
* (dts, dts-hd, dts:x ...). Grund: DTS macht ueber HDMI bei manchen AVRs (Denon)
|
||||||
|
* A/V-Sync-Probleme; EAC3 ist robust. TrueHD/AC3/EAC3 sind unproblematisch ->
|
||||||
|
* dann passiert nichts (Datei laeuft unveraendert weiter).
|
||||||
|
* Einzuhaengen im "nur kopieren"-Zweig: 02_Detect_1080p Output 2 -> HIER -> 05_Finalize_Move
|
||||||
|
* @author Sascha
|
||||||
|
* @revision 2
|
||||||
|
* @output OK (mit oder ohne neue Spur) -> weiter zu Finalize_Move
|
||||||
|
* @output Fehler
|
||||||
|
*/
|
||||||
|
function Script()
|
||||||
|
{
|
||||||
|
// Variables.vi.VideoInfo ist im ScriptNode unzuverlaessig (leer oder verzoegert;
|
||||||
|
// verifiziert 2026-07-06). Audio-Info daher direkt per ffprobe holen -> echte Kanalzahlen.
|
||||||
|
function probeAudio() {
|
||||||
|
var probe = null;
|
||||||
|
try { probe = Flow.GetToolPath('ffprobe'); } catch (e) {}
|
||||||
|
if (!probe) probe = Variables['ffprobe'] || 'ffprobe';
|
||||||
|
var res = Flow.Execute({
|
||||||
|
command: probe,
|
||||||
|
argumentList: ['-v', 'quiet', '-print_format', 'json', '-show_streams', Flow.WorkingFile]
|
||||||
|
});
|
||||||
|
if (!res || res.exitCode !== 0) { Logger.WLog('ffprobe fehlgeschlagen'); return null; }
|
||||||
|
var j;
|
||||||
|
try { j = JSON.parse(res.standardOutput || res.output || ''); } catch (e) { Logger.WLog('ffprobe JSON-Fehler: ' + e); return null; }
|
||||||
|
var streams = j.streams || [], auds = [];
|
||||||
|
for (var i = 0; i < streams.length; i++) {
|
||||||
|
var s = streams[i];
|
||||||
|
if (s.codec_type !== 'audio') continue;
|
||||||
|
var t = s.tags || {}, disp = s.disposition || {};
|
||||||
|
auds.push({ Language: t.language || '', Codec: (s.codec_name || ''),
|
||||||
|
Channels: s.channels || 0, Title: t.title || '', Default: (disp.default === 1) });
|
||||||
|
}
|
||||||
|
return auds;
|
||||||
|
}
|
||||||
|
|
||||||
|
let audioStreams = probeAudio();
|
||||||
|
if (audioStreams === null) { Logger.WLog('Keine Audio-Info (ffprobe) - ueberspringe'); return 1; }
|
||||||
|
|
||||||
|
function langOf(a) { return ('' + (a.Language || '')).toLowerCase().trim(); }
|
||||||
|
function isGerman(a) { let l = langOf(a); return (l === 'ger' || l === 'deu' || l === 'de'); }
|
||||||
|
function acodec(a) { return ('' + (a.Codec || '')).toLowerCase(); }
|
||||||
|
function isDts(a) { return acodec(a).indexOf('dts') === 0; } // dts, dts-hd, dts:x ...
|
||||||
|
function channels(a) { return parseInt(a.Channels, 10) || 0; } // ffprobe liefert echte Kanalzahl
|
||||||
|
function atitle(a) { return '' + (a.Title || a.Name || ''); }
|
||||||
|
// von UNS frueher erzeugte EAC3-Kompatspur (Titel-Tag) -> beim Neu-Mux verwerfen (idempotent).
|
||||||
|
function isOldCompat(a) { return acodec(a).indexOf('eac3') !== -1 && atitle(a).indexOf('AVR-kompatibel') !== -1; }
|
||||||
|
|
||||||
|
// beste deutsche spur (meiste kanaele) + relativer audio-index (position im array, fuer -map 0:a:N)
|
||||||
|
let bestGer = null, bestGerAIdx = -1, excludeIdx = -1;
|
||||||
|
for (let i = 0; i < audioStreams.length; i++) {
|
||||||
|
if (isOldCompat(audioStreams[i])) { excludeIdx = i; continue; } // alte Kompatspur ignorieren
|
||||||
|
if (isGerman(audioStreams[i])) {
|
||||||
|
if (!bestGer || channels(audioStreams[i]) > channels(bestGer)) {
|
||||||
|
bestGer = audioStreams[i]; bestGerAIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestGer === null) {
|
||||||
|
Logger.ILog('EAC3-Kompatspur: keine deutsche Tonspur - Datei unveraendert weiter.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!isDts(bestGer)) {
|
||||||
|
Logger.ILog('EAC3-Kompatspur: beste DE-Spur ist ' + acodec(bestGer) +
|
||||||
|
' (kein DTS) - unproblematisch, Datei unveraendert weiter.');
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -> beste DE-spur ist DTS: EAC3-kompatspur davor haengen, video + rest 1:1 kopieren
|
||||||
|
let ch = channels(bestGer) || 6;
|
||||||
|
let outCh = (ch >= 6) ? 6 : (ch >= 2 ? ch : 2); // EAC3 max 5.1 (ffmpeg-limit)
|
||||||
|
Logger.ILog('EAC3-Kompatspur: beste DE-Spur ist DTS (' + acodec(bestGer) + ' ' + ch +
|
||||||
|
'ch, Audio-Index ' + bestGerAIdx + ') -> haenge EAC3 ' + outCh + 'ch als Default an (Video COPY).');
|
||||||
|
|
||||||
|
let inFile = Flow.WorkingFile;
|
||||||
|
let outFile = Flow.TempPath + '/' + (Variables['file.Name'] || (Flow.NewGuid() + '.mkv'));
|
||||||
|
let ffmpeg = Flow.GetToolPath('ffmpeg') || Variables['ffmpeg'];
|
||||||
|
|
||||||
|
// verifizierte ffmpeg-syntax:
|
||||||
|
// -map 0:a:<de> -map 0:a -> EAC3-quelle als slot0, dann ALLE originale
|
||||||
|
// -c:a copy -c:a:0 eac3 -> alle copy AUSSER slot0
|
||||||
|
// -disposition:a 0 -disposition:a:0 default -> nur slot0 ist default
|
||||||
|
let args = ['-hide_banner', '-y', '-i', inFile,
|
||||||
|
'-map', '0:v', '-c:v', 'copy',
|
||||||
|
'-map', '0:a:' + bestGerAIdx, '-map', '0:a'];
|
||||||
|
if (excludeIdx >= 0) args.push('-map', '-0:a:' + excludeIdx); // alte Kompatspur raus
|
||||||
|
args.push('-c:a', 'copy', '-c:a:0', 'eac3', '-ac:a:0', '' + outCh,
|
||||||
|
'-b:a:0', (outCh >= 6 ? '640k' : '256k'),
|
||||||
|
'-metadata:s:a:0', 'title=Deutsch (EAC3 AVR-kompatibel)',
|
||||||
|
'-metadata:s:a:0', 'language=ger',
|
||||||
|
'-disposition:a', '0', '-disposition:a:0', 'default',
|
||||||
|
'-map', '0:s?', '-c:s', 'copy',
|
||||||
|
'-map', '0:t?', '-c:t', 'copy',
|
||||||
|
'-dn', '-max_muxing_queue_size', '9999',
|
||||||
|
outFile);
|
||||||
|
|
||||||
|
Logger.ILog('FFmpeg: ' + args.join(' '));
|
||||||
|
let result = Flow.Execute({ command: ffmpeg, argumentList: args });
|
||||||
|
|
||||||
|
if (!result || result.exitCode !== 0) {
|
||||||
|
Logger.ELog('EAC3-Anhaengen fehlgeschlagen (exit=' + (result ? result.exitCode : '?') + ')');
|
||||||
|
if (result && result.standardError) Logger.ELog(result.standardError);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Flow.SetWorkingFile(outFile);
|
||||||
|
Logger.ILog('EAC3-Kompatspur angehaengt -> ' + outFile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue