UNPKG

subsrt-ts

Version:

Subtitle JavaScript library and command line tool with no dependencies.

226 lines (205 loc) 6.97 kB
import { readFileSync, writeFileSync } from "fs"; import { extname } from "path"; // eslint-disable-next-line import/no-unresolved import { build as _build, convert as _convert, detect as _detect, list as _list, parse as _parse } from "./dist/subsrt.js"; const config = { verbose: process.env.NODE_VERBOSE === "true" || process.env.NODE_VERBOSE === "1", }; // Prints help message const help = () => { console.log("Usage:"); console.log(" subsrt [command] [options]"); console.log(""); console.log("Commands:"); console.log(" list List supported formats"); console.log(" parse [src] [json] Parse a subtitle file"); console.log(" build [json] [dst] Create a subtitle file from captions"); console.log(" detect [src] Detect subtitle file format, if supported"); console.log(" resync [src] [dst] Resync FPS or shift time (+/- offset)"); console.log(" convert [src] [dst] Converts a subtitle format"); console.log(""); console.log("Options:"); console.log(" --help Print this message"); console.log(" --eol [chars] End of line chars, e.g. \\r\\n"); console.log(" --fps [fps] Frames per second for .sub format"); console.log(" --offset [time] Resync time shift offset in ms"); console.log(" --format [ext] Subtitle format to convert/build/parse"); console.log(" --verbose Enable detailed logging"); console.log(" --version Print version number"); console.log(""); console.log("Examples:"); console.log(" subsrt parse sample.sbv"); console.log(" subsrt parse sample.srt output.json"); console.log(" subsrt parse sample.sub --fps 30"); console.log(" subsrt build input.json output.vtt"); console.log(" subsrt build input.json --format sbv"); console.log(" subsrt detect unknown.txt"); console.log(" subsrt convert sample.srt sample.vtt"); console.log(" subsrt convert --offset -250 sample.srt sample.ssa"); console.log(" subsrt resync --offset +3000 input.srt output.srt"); console.log(" subsrt resync --fps 25-30 input.sub output.sub"); }; // Command line arguments const args = process.argv.slice(2); for (let i = 0; i < args.length; i++) { switch (args[i]) { case "list": case "parse": case "build": case "detect": case "resync": case "convert": if (config.command) { throw new Error(`Cannot run more than one command: ${args[i]}`); } config.command = args[i]; break; case "--eol": config.eol = args[++i]; if (config.eol) { config.eol = config.eol.replace(/\\r/g, "\r").replace(/\\n/g, "\n"); } break; case "--fps": { let fps = args[++i]; if (fps.indexOf("-") > 0) { fps = fps.split("-"); config.fpsFrom = parseFloat(fps[0]); config.fpsTo = parseFloat(fps[1]); } else { config.fps = parseFloat(fps); } break; } case "--offset": config.offset = parseInt(args[++i], 10); break; case "--format": config.format = args[++i]; break; case "--help": help(); config.exit = true; break; case "--verbose": config.verbose = true; break; case "--version": console.log((await import("./package.json")).version); config.exit = true; break; default: if (!config.src) { config.src = args[i]; continue; } if (!config.dst) { config.dst = args[i]; continue; } throw new Error(`Unknown command line argument: ${args[i]}`); } } const commands = { list: () => { console.log(_list().join(", ")); }, parse: () => { const content = readFileSync(config.src, "utf8"); const options = { verbose: config.verbose, }; if (config.fps) { options.fps = config.fps; } const captions = _parse(content, options); const json = JSON.stringify(captions, " ", 2); if (config.dst) { writeFileSync(config.dst, json); } else { console.log(json); } }, build: () => { const json = readFileSync(config.src, "utf8"); const captions = JSON.parse(json); if (!config.format && config.dst) { const ext = extname(config.dst); config.format = ext.replace(/\./, "").toLowerCase(); } const options = { verbose: config.verbose, format: config.format, }; if (config.fps) { options.fps = config.fps; } if (config.eol) { options.eol = config.eol; } const content = _build(captions, options); if (config.dst) { writeFileSync(config.dst, content); } else { console.log(content); } }, detect: () => { const content = readFileSync(config.src, "utf8"); const format = _detect(content); console.log(format || "unknown"); }, resync: () => { const options = {}; if (config.offset) { options.offset = config.offset; } if (config.fpsFrom && config.fpsTo) { options.ratio = config.fpsTo / config.fpsFrom; options.frame = true; } if (config.fps) { options.fps = config.fps; } if (config.fpsFrom) { options.fps = config.fpsFrom; options.frame = true; } config.resync = options; commands.convert(); }, convert: () => { const content = readFileSync(config.src, "utf8"); if (!config.format && config.dst) { const ext = extname(config.dst); config.format = ext.replace(/\./, "").toLowerCase(); } const options = { verbose: config.verbose, format: config.format, }; if (config.fps) { options.fps = config.fps; } if (config.eol) { options.eol = config.eol; } if (config.resync) { options.resync = config.resync; } const converted = _convert(content, options); if (config.dst) { writeFileSync(config.dst, converted); } else { console.log(converted); } }, }; if (!config.exit) { const func = commands[config.command]; if (typeof func === "function") { func(); } else { help(); } }