timecode-converter
Version:
Modern TypeScript library for broadcast timecode conversions with full SMPTE drop-frame support
105 lines (98 loc) • 3.92 kB
text/typescript
/**
* Frame rate in frames per second
* Common values: 24, 25, 29.97, 30, 50, 59.94
* WARNING: 29.97 is treated as non-drop frame
*/
type FrameRate = number;
/**
* Timecode string in format:
* - Non-drop frame: hh:mm:ss:ff (colons)
* - Drop-frame: hh:mm:ss;ff (semicolon before frames)
*/
type TimecodeFormat = string;
type Seconds = number;
interface TimecodeOptions {
frameRate?: FrameRate;
}
/**
* Convert seconds to broadcast timecode format
* @param seconds - Time in seconds
* @param frameRate - Frames per second (required)
* @param dropFrame - Generate drop-frame format. If not specified:
* - For 29.97/59.94 fps: Uses drop-frame for durations ≥ 1 minute
* - For other frame rates: Always non-drop frame
* @returns Timecode in format:
* - Non-drop: hh:mm:ss:ff (colons)
* - Drop-frame: hh:mm:ss;ff (semicolon before frames)
* @example
* secondsToTimecode(3600, 29.97) // "01:00:00;00" (auto drop-frame)
* secondsToTimecode(30, 29.97) // "00:00:30:00" (auto non-drop for short duration)
* secondsToTimecode(3600, 29.97, false) // "01:00:00:00" (forced non-drop)
* secondsToTimecode(3600, 25) // "01:00:00:00" (always non-drop for PAL)
*/
declare const secondsToTimecode: (seconds: Seconds, frameRate: FrameRate, dropFrame?: boolean) => TimecodeFormat;
interface TimecodeValidationResult {
valid: boolean;
errors: string[];
warnings: string[];
format?: "drop-frame" | "non-drop";
components?: {
hours: number;
minutes: number;
seconds: number;
frames: number;
};
}
/**
* Validate a timecode string and provide detailed feedback
* @param timecode - Timecode string to validate
* @param frameRate - Frame rate to validate against (optional)
* @returns Validation result with errors, warnings, and parsed components
* @example
* validateTimecode("01:00:00;00", 29.97)
* // { valid: true, format: "drop-frame", components: {...} }
*
* validateTimecode("25:00:00:00", 25)
* // { valid: false, errors: ["Hours cannot exceed 23"] }
*
* validateTimecode("00:00:00;00", 25)
* // { valid: true, warnings: ["Drop-frame format used with non-drop-frame rate 25 fps"] }
*/
declare function validateTimecode(timecode: TimecodeFormat, frameRate?: FrameRate): TimecodeValidationResult;
/**
* Check if a timecode string is in drop-frame format
* Drop-frame timecodes use semicolon before frames: hh:mm:ss;ff
*/
declare const isDropFrameTimecode: (tc: string) => boolean;
/**
* Check if a frame rate supports drop-frame
* Only 29.97 and 59.94 fps support drop-frame in SMPTE standard
*/
declare const isDropFrameRate: (fps: FrameRate) => boolean;
/**
* Wrapping around "time stamps" and timecode conversion modules
* To provide more support for variety of formats.
*/
/**
* Convert various time formats to seconds
* @param time - Can take as input timecodes in the following formats:
* - hh:mm:ss:ff
* - mm:ss
* - m:ss
* - ss - seconds --> if it's already in seconds then it just returns seconds
* - hh:mm:ff
* - m.ss
* @param frameRate - Frames per second (must be specified for timecode strings)
* @returns Time in seconds
* @todo could be refactored with some helper functions for clarity
*/
declare const timecodeToSeconds: (time: string | number, frameRate?: number) => Seconds;
/**
* Get shortened timecode without frames
* @param time - Time in seconds or timecode format
* @param frameRate - Frames per second (required)
* @param dropFrame - Generate drop-frame format (auto-detected from input format if string)
* @returns Timecode in format hh:mm:ss
*/
declare const shortTimecode: (time: number | string, frameRate: number, dropFrame?: boolean) => string;
export { type FrameRate, type Seconds, type TimecodeFormat, type TimecodeOptions, type TimecodeValidationResult, isDropFrameRate, isDropFrameTimecode, secondsToTimecode, shortTimecode, timecodeToSeconds, validateTimecode };