UNPKG

subforge

Version:

High-performance subtitle toolkit for parsing, converting, and authoring across 20+ formats.

116 lines (106 loc) 3.7 kB
/** * Options for CAP timecode parsing. */ export interface CAPTimecodeOptions { /** Frames per second (defaults to 25 for PAL) */ fps?: number } /** * Parses CAP timecode string to milliseconds. * * CAP uses frame-accurate timecode format: HH:MM:SS:FF where FF is the frame number. * The frame count is converted to milliseconds based on the specified fps. * * @param s - Timecode string in HH:MM:SS:FF format * @param fps - Frames per second for frame-to-time conversion (defaults to 25) * @returns Time in milliseconds * @throws {Error} If the timecode format is invalid or contains non-numeric values * * @example * ```ts * const ms = parseTime('00:00:01:12', 25); * // Returns 1480 (1 second + 12 frames at 25fps) * ``` */ export function parseTime(s: string, fps: number = 25): number { // CAP format: HH:MM:SS:FF (frames) const parts = s.split(':') if (parts.length !== 4) throw new Error(`Invalid CAP timecode: ${s}`) const h = parseInt(parts[0]!, 10) const m = parseInt(parts[1]!, 10) const ss = parseInt(parts[2]!, 10) const ff = parseInt(parts[3]!, 10) if (isNaN(h) || isNaN(m) || isNaN(ss) || isNaN(ff)) { throw new Error(`Invalid CAP timecode: ${s}`) } // Convert frames to milliseconds const frameMs = (ff / fps) * 1000 return h * 3600000 + m * 60000 + ss * 1000 + frameMs } /** * Formats milliseconds to CAP timecode string. * * Converts milliseconds to frame-accurate timecode format (HH:MM:SS:FF). * The frame number is calculated by converting the remaining milliseconds to frames * based on the specified fps. * * @param ms - Time in milliseconds * @param fps - Frames per second for time-to-frame conversion (defaults to 25) * @returns Formatted timecode string in HH:MM:SS:FF format * * @example * ```ts * const timecode = formatTime(1480, 25); * // Returns '00:00:01:12' (1 second + 12 frames) * ``` */ export function formatTime(ms: number, fps: number = 25): string { const h = Math.floor(ms / 3600000) const m = Math.floor((ms % 3600000) / 60000) const s = Math.floor((ms % 60000) / 1000) const remainingMs = ms % 1000 // Convert milliseconds to frames const ff = Math.round((remainingMs / 1000) * fps) return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}:${ff.toString().padStart(2, '0')}` } /** * Converts video standard name to frames per second. * * Maps standard video format names to their corresponding frame rates. * Supports PAL (25fps) and NTSC (29.97fps). Defaults to PAL for unknown standards. * * @param standard - Video standard name (case-insensitive: 'PAL' or 'NTSC') * @returns Frame rate (25 for PAL, 29.97 for NTSC, 25 for unknown) * * @example * ```ts * const fps = videoStandardToFps('NTSC'); // Returns 29.97 * const palFps = videoStandardToFps('pal'); // Returns 25 (case-insensitive) * ``` */ export function videoStandardToFps(standard: string): number { const normalized = standard.toUpperCase() if (normalized === 'PAL') return 25 if (normalized === 'NTSC') return 29.97 // Default to PAL if unknown return 25 } /** * Converts frame rate to video standard name. * * Determines the video standard based on the frame rate value. * Frame rates close to 29.97 are considered NTSC, all others default to PAL. * * @param fps - Frame rate value * @returns Video standard name ('NTSC' or 'PAL') * * @example * ```ts * const standard = fpsToVideoStandard(29.97); // Returns 'NTSC' * const palStandard = fpsToVideoStandard(25); // Returns 'PAL' * ``` */ export function fpsToVideoStandard(fps: number): string { if (Math.abs(fps - 29.97) < 0.1) return 'NTSC' return 'PAL' }