UNPKG

subsrt-ts

Version:

Subtitle JavaScript library and command line tool with no dependencies.

84 lines (83 loc) 3.17 kB
import { buildHandler } from "../handler.js"; const FORMAT_NAME = "sub"; const DEFAULT_FPS = 25; /** * Parses captions in MicroDVD format. * @param content The subtitle content * @param options Parse options * @returns Parsed captions * @see https://en.wikipedia.org/wiki/MicroDVD */ const parse = (content, options) => { var _a; options.fps || (options.fps = DEFAULT_FPS); const fps = options.fps > 0 ? options.fps : DEFAULT_FPS; const captions = []; const eol = (_a = options.eol) !== null && _a !== void 0 ? _a : "\r\n"; const parts = content.split(/\r?\n/); for (let i = 0; i < parts.length; i++) { const regex = /^\{(\d+)\}\{(\d+)\}(.*)$/; const match = regex.exec(parts[i]); if (match) { const caption = {}; caption.type = "caption"; caption.index = i + 1; caption.frame = { start: parseInt(match[1], 10), end: parseInt(match[2], 10), count: parseInt(match[2]) - parseInt(match[1], 10), }; caption.start = Math.round(caption.frame.start / fps); caption.end = Math.round(caption.frame.end / fps); caption.duration = caption.end - caption.start; const lines = match[3].split(/\|/); caption.content = lines.join(eol); caption.text = caption.content.replace(/\{[^}]+\}/g, ""); // {0}{25}{c:$0000ff}{y:b,u}{f:DeJaVuSans}{s:12}Hello! captions.push(caption); continue; } if (options.verbose) { console.warn("Unknown part", parts[i]); } } return captions; }; /** * Builds captions in MicroDVD format. * @param captions The captions to build * @param options Build options * @returns The built captions string in MicroDVD format * @see https://en.wikipedia.org/wiki/MicroDVD */ const build = (captions, options) => { var _a, _b; const fps = ((_a = options.fps) !== null && _a !== void 0 ? _a : 0) > 0 ? options.fps : DEFAULT_FPS; let sub = ""; const eol = (_b = options.eol) !== null && _b !== void 0 ? _b : "\r\n"; for (const caption of captions) { if (!caption.type || caption.type === "caption") { const startFrame = typeof caption.frame === "object" && caption.frame.start >= 0 ? caption.frame.start : caption.start * fps; const endFrame = typeof caption.frame === "object" && caption.frame.end >= 0 ? caption.frame.end : caption.end * fps; const text = caption.text.replace(/\r?\n/, "|"); sub += `{${startFrame}}{${endFrame}}${text}${eol}`; continue; } if (options.verbose) { console.log("SKIP:", caption); } } return sub; }; /** * Detects whether the content is in MicroDVD format. * @param content The subtitle content * @returns Whether it's MicroDVD format */ const detect = (content) => { /* {7207}{7262}Sister, perfume? */ return /^\{\d+\}\{\d+\}.*/.test(content); }; export default buildHandler({ name: FORMAT_NAME, build, detect, parse }); export { FORMAT_NAME as name, build, detect, parse };