'use strict'; const path = require('path'); const fs = require('fs'); /* eslint-disable no-param-reassign */ const details = () => ({ name: 'Extract Chapters to XML', description: 'Extracts MKV chapter markers to an XML file next to the original source using mkvextract. ' + 'Stores the output path in args.variables.chaptersXmlPath. ' + 'Safe to run even if the source has no chapters.', style: { borderColor: '#9C27B0' }, tags: 'utility,chapters,mkv', isStartPlugin: false, pType: '', requiresVersion: '2.11.01', sidebarPosition: -1, icon: 'faList', inputs: [], outputs: [ { number: 1, tooltip: 'Continue to next plugin' }, ], }); const plugin = async (args) => { const { jobLog, inputFileObj, variables, workDir, updateWorker } = args; const inputFile = inputFileObj._id; // Keep sidecar files in the library when a prior plugin copied the media to workDir. const originalFile = variables.originalLibraryFile || inputFile; const targetDir = variables.originalLibraryDir || path.dirname(originalFile); const baseName = path.basename(originalFile, path.extname(originalFile)); const xmlPath = path.join(targetDir, `${baseName}_chapters.xml`); jobLog(`[extractChaptersXml] Source: ${inputFile}\n`); jobLog(`[extractChaptersXml] Output: ${xmlPath}\n`); // Derive mkvextract from mkvpropeditPath (same MKVToolNix bin dir) let mkvExtract = 'mkvextract'; if (args.mkvpropeditPath) { const dir = path.dirname(args.mkvpropeditPath); const candidate = path.join(dir, process.platform === 'win32' ? 'mkvextract.exe' : 'mkvextract'); if (fs.existsSync(candidate)) mkvExtract = candidate; } jobLog(`[extractChaptersXml] Using: ${mkvExtract}\n`); const { CLI } = require('../../../../FlowHelpers/1.0.0/cliUtils'); const cli = new CLI({ cli: mkvExtract, spawnArgs: [inputFile, 'chapters', xmlPath], WorkDir: workDir, jobLog, inputFileObj, updateWorker, args, }); const { cliExitCode } = await cli.runCli(); // mkvextract: exit 0 = OK, exit 1 = no chapters (still OK), exit 2 = error if (cliExitCode > 1) { jobLog(`[extractChaptersXml] WARNING: mkvextract exit ${cliExitCode} — chapters may be missing.\n`); variables.chaptersXmlPath = ''; } else if (fs.existsSync(xmlPath) && fs.statSync(xmlPath).size > 50) { variables.chaptersXmlPath = xmlPath; jobLog(`[extractChaptersXml] Chapters saved: ${xmlPath}\n`); } else { jobLog('[extractChaptersXml] No chapters found.\n'); variables.chaptersXmlPath = ''; } return { outputNumber: 1, outputFileObj: inputFileObj, variables }; }; module.exports.details = details; module.exports.plugin = plugin;