@codedimension/video-editor
Advanced tools
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.validateAndCorrectPath = validateAndCorrectPath; | ||
| const chalk_1 = __importDefault(require("chalk")); | ||
| /** | ||
| * Tokenizes and parses option flags swallowed into a corrupted string. | ||
| */ | ||
| function parseSwallowedOptions(swallowed) { | ||
| const options = {}; | ||
| const regex = /[^\s"']+|"([^"]*)"|'([^']*)'/g; | ||
| const tokens = []; | ||
| let match; | ||
| while ((match = regex.exec(swallowed)) !== null) { | ||
| tokens.push(match[1] || match[2] || match[0]); | ||
| } | ||
| for (let i = 0; i < tokens.length; i++) { | ||
| const token = tokens[i]; | ||
| if (token.startsWith("--")) { | ||
| const name = token.slice(2); | ||
| const camelName = name.replace(/-([a-z])/g, (g) => g[1].toUpperCase()); | ||
| if (i + 1 < tokens.length && !tokens[i + 1].startsWith("-")) { | ||
| options[camelName] = tokens[i + 1]; | ||
| i++; | ||
| } | ||
| else { | ||
| options[camelName] = true; | ||
| } | ||
| } | ||
| } | ||
| return options; | ||
| } | ||
| /** | ||
| * Validates a path argument/option and automatically corrects trailing backslash corruption. | ||
| * Recovers any options/arguments that were swallowed by the OS shell argument serialization. | ||
| */ | ||
| function validateAndCorrectPath(value, name, options) { | ||
| if (!value) | ||
| return value; | ||
| // Corruption detection: contains quote or option flag syntax | ||
| if (value.includes('"') || value.includes("--")) { | ||
| let cleanPath = value; | ||
| let swallowed = ""; | ||
| if (value.includes('"')) { | ||
| const parts = value.split('"'); | ||
| cleanPath = parts[0]; | ||
| swallowed = parts.slice(1).join('"'); | ||
| } | ||
| else if (value.includes("--")) { | ||
| const idx = value.indexOf("--"); | ||
| cleanPath = value.slice(0, idx); | ||
| swallowed = value.slice(idx); | ||
| } | ||
| // Clean up trailing/leading spaces and backslashes | ||
| cleanPath = cleanPath.trim(); | ||
| if (cleanPath.endsWith("\\") && !cleanPath.endsWith(":\\")) { | ||
| cleanPath = cleanPath.slice(0, -1); | ||
| } | ||
| console.warn(chalk_1.default.yellow(`Warning: The ${name.startsWith("-") ? "option" : "path"} "${name}" was corrupted due to a trailing backslash on Windows.`)); | ||
| console.warn(chalk_1.default.yellow(`Automatically corrected path to: "${cleanPath}"`)); | ||
| if (swallowed && options) { | ||
| const parsed = parseSwallowedOptions(swallowed); | ||
| if (Object.keys(parsed).length > 0) { | ||
| console.warn(chalk_1.default.yellow(`Automatically recovered swallowed options: ${JSON.stringify(parsed)}`)); | ||
| Object.assign(options, parsed); | ||
| } | ||
| } | ||
| return cleanPath; | ||
| } | ||
| return value; | ||
| } |
@@ -47,2 +47,3 @@ "use strict"; | ||
| const media_1 = require("../utils/media"); | ||
| const validation_1 = require("../utils/validation"); | ||
| const execAsync = (0, util_1.promisify)(child_process_1.exec); | ||
@@ -62,4 +63,4 @@ async function checkFfmpeg() { | ||
| .description("Merge multiple .mkv files in a directory into a single .mp4 file, automatically trimming silence.") | ||
| .requiredOption("--videosDir <path>", "directory containing .mkv video files") | ||
| .requiredOption("--outputFile <path>", "path for the output .mp4 file") | ||
| .option("--videosDir <path>", "directory containing .mkv video files") | ||
| .option("--outputFile <path>", "path for the output .mp4 file") | ||
| .option("--start-padding <seconds>", "Start padding (safety margin) in seconds", "0.1") | ||
@@ -69,2 +70,12 @@ .option("--end-padding <seconds>", "End padding (safety margin) in seconds", "0.2") | ||
| .action(async (options) => { | ||
| options.videosDir = (0, validation_1.validateAndCorrectPath)(options.videosDir, "--videosDir", options); | ||
| options.outputFile = (0, validation_1.validateAndCorrectPath)(options.outputFile, "--outputFile", options); | ||
| if (!options.videosDir) { | ||
| console.error(chalk_1.default.red("error: required option '--videosDir <path>' not specified")); | ||
| process.exit(1); | ||
| } | ||
| if (!options.outputFile) { | ||
| console.error(chalk_1.default.red("error: required option '--outputFile <path>' not specified")); | ||
| process.exit(1); | ||
| } | ||
| const videosDir = path.resolve(options.videosDir); | ||
@@ -71,0 +82,0 @@ const outputFile = path.resolve(options.outputFile); |
@@ -49,2 +49,3 @@ "use strict"; | ||
| const media_1 = require("../utils/media"); | ||
| const validation_1 = require("../utils/validation"); | ||
| const execAsync = (0, util_1.promisify)(child_process_1.exec); | ||
@@ -120,2 +121,3 @@ async function checkFfmpeg() { | ||
| .action(async (coursePath, options) => { | ||
| coursePath = (0, validation_1.validateAndCorrectPath)(coursePath, "<coursePath>", options) || coursePath; | ||
| const rootPath = path.resolve(coursePath); | ||
@@ -122,0 +124,0 @@ const naoEditadoPath = path.join(rootPath, "nao-editado"); |
@@ -45,2 +45,3 @@ "use strict"; | ||
| const cli_progress_1 = __importDefault(require("cli-progress")); | ||
| const validation_1 = require("../utils/validation"); | ||
| /** | ||
@@ -64,2 +65,3 @@ * Natural sort function for filenames. | ||
| .action(async (directory, options) => { | ||
| directory = (0, validation_1.validateAndCorrectPath)(directory, "[directory]", options) || directory; | ||
| const targetDir = path.resolve(directory); | ||
@@ -66,0 +68,0 @@ const startPadding = parseFloat(options.startPadding); |
@@ -45,2 +45,3 @@ "use strict"; | ||
| const media_1 = require("../utils/media"); | ||
| const validation_1 = require("../utils/validation"); | ||
| function registerTrimSilenceCommand(program) { | ||
@@ -50,4 +51,4 @@ program | ||
| .description("Remove silence from the beginning and end of .mkv files.") | ||
| .requiredOption("--input <path>", "input .mkv file or directory") | ||
| .requiredOption("--output <path>", "output directory (or file if input is a single file)") | ||
| .option("--input <path>", "input .mkv file or directory") | ||
| .option("--output <path>", "output directory (or file if input is a single file)") | ||
| .option("--start-padding <seconds>", "Start padding (safety margin) in seconds", "0.1") | ||
@@ -57,2 +58,12 @@ .option("--end-padding <seconds>", "End padding (safety margin) in seconds", "0.2") | ||
| .action(async (options) => { | ||
| options.input = (0, validation_1.validateAndCorrectPath)(options.input, "--input", options); | ||
| options.output = (0, validation_1.validateAndCorrectPath)(options.output, "--output", options); | ||
| if (!options.input) { | ||
| console.error(chalk_1.default.red("error: required option '--input <path>' not specified")); | ||
| process.exit(1); | ||
| } | ||
| if (!options.output) { | ||
| console.error(chalk_1.default.red("error: required option '--output <path>' not specified")); | ||
| process.exit(1); | ||
| } | ||
| const inputPath = path.resolve(options.input); | ||
@@ -59,0 +70,0 @@ const outputPath = path.resolve(options.output); |
+1
-1
| { | ||
| "name": "@codedimension/video-editor", | ||
| "version": "1.2.1", | ||
| "version": "1.2.2", | ||
| "description": "Video Editor CLI merges .mkv files to a single .mp4 file", | ||
@@ -5,0 +5,0 @@ "files": [ |
62893
7.63%9
12.5%1246
8.63%