feat: Tdarr Local Flow Plugin Suite v1.0

7 atomic plugins for automated x265 transcoding pipeline:
- utility/mediaAnalyzerGOP    : GOP calc, FPS detection, film/series/anime routing
- utility/setAnimationFlag    : manual animation flag override
- utility/extractChaptersXml  : mkvextract chapters to XML
- audio/audioSelectorClamping : codec scoring, clamped Opus bitrates, 2 outputs
- audio/backupSourceAudio     : lossless DTS/TrueHD ITA backup (-c:a copy)
- subtitles/extractSubtitlesAndOcr : SRT extract + SubtitleEdit OCR for PGS
- video/transcode2PassX265    : 2-pass x265, Lanczos 1080p bound, Opus mux

Test suite: 34 unit tests + 3 integration tests (FFmpeg real files)
FlowHelpers mock for local testing included
Docs: integration-guide.md with canvas wiring and deploy instructions
This commit is contained in:
PickleRick committed 2026-09-18 23:23:05 +02:00
commit c2074be826
19 files changed
+2134

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
'use strict';
/**
* Local mock of Tdarr FlowHelpers/1.0.0/cliUtils.js
* Used only for local testing — on real Tdarr this file comes from the server.
*/
const { spawn } = require('child_process');
class CLI {
constructor(config) {
this.config = config;
}
runCli() {
return new Promise((resolve) => {
const { cli, spawnArgs, WorkDir, jobLog } = this.config;
if (jobLog) jobLog(`[CLI] Running: ${cli} ${spawnArgs.join(' ')}\n`);
const proc = spawn(cli, spawnArgs, {
cwd: WorkDir || process.cwd(),
stdio: ['ignore', 'pipe', 'pipe'],
shell: false,
});
proc.stdout.on('data', (d) => { if (jobLog) jobLog(d.toString()); });
proc.stderr.on('data', (d) => { if (jobLog) jobLog(d.toString()); });
proc.on('close', (code) => {
resolve({ cliExitCode: code || 0 });
});
proc.on('error', (err) => {
if (jobLog) jobLog(`[CLI] Error: ${err.message}\n`);
resolve({ cliExitCode: 1 });
});
});
}
}
const getFFmpegVar = () => {};
module.exports = { CLI, getFFmpegVar };
+12
View File
@@ -0,0 +1,12 @@
'use strict';
/**
* Local mock of Tdarr FlowHelpers/1.0.0/fileUtils.js
*/
const fs = require('fs');
const path = require('path');
const moveFile = (src, dest) => fs.renameSync(src, dest);
const copyFile = (src, dest) => fs.copyFileSync(src, dest);
const getFileSize = (fp) => { try { return fs.statSync(fp).size; } catch(_) { return 0; } };
module.exports = { moveFile, copyFile, getFileSize };