Files
Tdarr-plugin/LocalFlowPlugins/audio/backupSourceAudio/1.0.0/index.js
T

101 lines
3.1 KiB
JavaScript

'use strict';
const path = require('path');
const fs = require('fs');
/* eslint-disable no-param-reassign */
/**
* backupSourceAudio
* Extracts the original ITA audio track as a lossless bitstream copy,
* ONLY when the codec is DTS or TrueHD.
* Output is saved next to the source file (same directory).
*/
const BACKUP_CODECS = ['dts', 'truehd'];
const details = () => ({
name: 'Backup Source Audio (DTS / TrueHD ITA)',
description:
'Extracts the ITA audio track as a lossless bitstream copy (-c:a copy) '
+ 'when the source codec is DTS or TrueHD. '
+ 'Output is saved next to the source file. '
+ 'Silently skips if the ITA track does not require backup.',
style: { borderColor: '#F44336' },
tags: 'audio,backup',
isStartPlugin: false,
pType: '',
requiresVersion: '2.11.01',
sidebarPosition: -1,
icon: 'faSave',
inputs: [],
outputs: [
{ number: 1, tooltip: 'Continue to next plugin' },
],
});
const plugin = async (args) => {
const { jobLog, inputFileObj, variables, workDir, updateWorker } = args;
const inputFile = inputFileObj._id;
jobLog(`[backupSourceAudio] Processing: ${inputFile}\n`);
const hasIta = variables.audioHasIta === 'true';
const itaCodec = (variables.audioItaCodecName || '').toLowerCase();
const itaIdx = variables.audioItaStreamIndex;
if (!hasIta) {
jobLog('[backupSourceAudio] No ITA track found — skipping.\n');
return { outputNumber: 1, outputFileObj: inputFileObj, variables };
}
const needsBackup = BACKUP_CODECS.some((c) => itaCodec.includes(c));
if (!needsBackup) {
jobLog(`[backupSourceAudio] ITA codec "${itaCodec}" does not require backup — skipping.\n`);
return { outputNumber: 1, outputFileObj: inputFileObj, variables };
}
// Determine output extension
let ext = '.dts';
if (itaCodec.includes('truehd')) ext = '.thd';
const targetDir = variables.originalLibraryDir || path.dirname(inputFile);
const baseName = path.basename(variables.originalLibraryFile || inputFile, path.extname(variables.originalLibraryFile || inputFile));
const outFile = path.join(targetDir, `${baseName}.ita${ext}`);
jobLog(`[backupSourceAudio] Backing up ITA ${itaCodec} -> ${outFile}\n`);
const { CLI } = require('../../../../FlowHelpers/1.0.0/cliUtils');
const cli = new CLI({
cli: args.ffmpegPath,
spawnArgs: [
'-y',
'-i', inputFile,
'-map', `0:${itaIdx}`,
'-c:a', 'copy',
outFile,
],
spawnOpts: { cwd: workDir },
WorkDir: workDir,
jobLog,
outputFilePath: outFile,
inputFileObj,
updateWorker,
logFullCliOutput: args.logFullCliOutput || false,
args,
});
const { cliExitCode } = await cli.runCli();
if (cliExitCode !== 0) {
jobLog(`[backupSourceAudio] WARNING: FFmpeg exited with code ${cliExitCode}. Backup may be incomplete.\n`);
} else {
jobLog(`[backupSourceAudio] Backup complete: ${outFile}\n`);
variables.audioBackupPath = outFile;
}
return { outputNumber: 1, outputFileObj: inputFileObj, variables };
};
module.exports.details = details;
module.exports.plugin = plugin;