diff --git a/.gitignore b/.gitignore index 0cd5b66..7527ce5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,10 @@ inputs/* outputs/* temp/* +subs/* + + +.DS_Store #---> Node # Logs diff --git a/src/command-config.js b/src/command-config.js index c845c88..15bf65d 100644 --- a/src/command-config.js +++ b/src/command-config.js @@ -1,3 +1,4 @@ +import { addSubtitleTrack } from "./commands/add-subs.js"; import { extractToEpisodeNumber } from "./commands/extract-to-se.js"; import { finalizeFileNames } from "./commands/finalize-filenames.js"; @@ -13,5 +14,11 @@ export const CommandConfig = [ commands: ['-o'], params: ['ShowName'], func: finalizeFileNames, + }, + { + name: 'Add Subtitle Track', + commands: ['-s'], + params: ['SubtitleDirectory'], + func: addSubtitleTrack, } ]; \ No newline at end of file diff --git a/src/commands/add-subs.js b/src/commands/add-subs.js new file mode 100644 index 0000000..11b0c46 --- /dev/null +++ b/src/commands/add-subs.js @@ -0,0 +1,36 @@ +import { getFilenameObject } from "../parsing/parse-filename.js"; +import fs from 'fs'; +import { exec } from "../shell/exec.js"; + +const AcceptedSubtitleExtensions = [ + '.srt', + '.ass', +]; + +export async function addSubtitleTrack(inputDir, inputFile, outputDir, { SubtitleDirectory }) { + const filenameObject = getFilenameObject(inputFile); + const subFileEntries = fs.readdirSync(SubtitleDirectory, { encoding: 'utf-8', withFileTypes: true }); + const subFilenameObjects = subFileEntries.filter( + ent => ent.isFile + ).map( + ent => getFilenameObject(ent.name) + ); + + const validSubFilenameObjects = subFilenameObjects.filter( + fno => AcceptedSubtitleExtensions.includes(fno.extension) + ); + + const match = validSubFilenameObjects.find( + fno => fno.prefix === filenameObject.prefix + ); + + if(match) { + await exec( + `ffmpeg -i ${inputDir}${inputFile} -i ${SubtitleDirectory}${match.fullName} -map 0 -map 1:s -c copy -metadata:s:s:0 language=eng -disposition:s:0 default ${outputDir}${filenameObject.prefix}.mkv` + ); + + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/src/commands/extract-to-se.js b/src/commands/extract-to-se.js index bf2af73..0616437 100644 --- a/src/commands/extract-to-se.js +++ b/src/commands/extract-to-se.js @@ -1,4 +1,5 @@ import fs from 'fs'; +import { getFilenameObject } from '../parsing/parse-filename.js'; const acceptedPatternMappings = [ { @@ -33,19 +34,15 @@ const acceptedPatternMappings = [ }, ]; -const extensionPattern = /(\..*)$/; - export async function extractToEpisodeNumber(inputDir, inputFile, outputDir, options) { for(let i = 0; i < acceptedPatternMappings.length; i++) { const matches = inputFile.match(acceptedPatternMappings[i].pattern); if(matches?.length > 0) { const outputFileName = acceptedPatternMappings[i].mapper(matches); - const extensionMatches = inputFile.match(extensionPattern); + const filenameObject = getFilenameObject(inputFile); - const extension = extensionMatches ? extensionMatches[1] : ''; - - const toWrite = `${outputDir}${outputFileName}${extension}`; + const toWrite = `${outputDir}${outputFileName}${filenameObject.extension}`; fs.cpSync(`${inputDir}${inputFile}`, `${toWrite}`); return true; diff --git a/src/parsing/parse-filename.js b/src/parsing/parse-filename.js new file mode 100644 index 0000000..b54271d --- /dev/null +++ b/src/parsing/parse-filename.js @@ -0,0 +1,24 @@ +const extensionPattern = /(\..*)$/; + +export function getFilenameObject(filenameString) { + const extensionMatches = filenameString.match(extensionPattern); + + if(extensionMatches?.length > 0) { + const extension = extensionMatches[1]; + + const len = extension.length; + const prefix = filenameString.slice(0, -1 * len); + + return { + prefix: prefix, + extension: extension, + fullName: filenameString, + }; + } else { + return { + prefix: filenameString, + extension: '', + fullName: filenameString, + }; + } +} \ No newline at end of file diff --git a/src/shell/exec.js b/src/shell/exec.js new file mode 100644 index 0000000..16e2c97 --- /dev/null +++ b/src/shell/exec.js @@ -0,0 +1,8 @@ +import child_process from 'node:child_process'; +import { promisify } from 'node:util'; + +const execPromise = promisify(child_process.exec); + +export async function exec(commandString) { + return await execPromise(commandString); +} \ No newline at end of file