A modern TypeScript library for broadcast timecode conversions with full SMPTE drop-frame support.
- 🎯 Accurate Conversions - Frame-accurate timecode to seconds conversions
- 🎬 SMPTE Drop-Frame - Full support for 29.97 and 59.94 fps drop-frame timecode
- 🤖 Smart Auto-Detection - Automatically handles drop-frame when appropriate
- 📦 TypeScript First - Written in TypeScript with strict types
- ✅ Validation - Built-in timecode validation with detailed error messages
- 🚀 Modern Build - Dual ESM/CJS builds, tree-shakeable
- 🔧 Zero Dependencies - No external runtime dependencies
- ⚡ High Performance - Optimized with improved floating-point precision
npm install timecode-converter # or pnpm add timecode-converter # or yarn add timecode-converterimport { secondsToTimecode, timecodeToSeconds } from 'timecode-converter' // Convert seconds to timecode secondsToTimecode(90, 29.97) // '00:01:29;29' (auto drop-frame) secondsToTimecode(90, 25) // '00:01:30:00' (PAL) // Convert timecode to seconds timecodeToSeconds('00:01:30:00', 25) // 90 timecodeToSeconds('00:01:29;29', 29.97) // 90 (auto-detects drop-frame)This library provides comprehensive SMPTE drop-frame timecode support with smart defaults.
Drop-frame is used with NTSC frame rates (29.97, 59.94 fps) to keep timecode aligned with real-world time. It works by skipping frame numbers 00 and 01 at the start of each minute, except every 10th minute.
The library intelligently handles drop-frame based on context:
// Parsing: Auto-detects from format (semicolon = drop-frame) timecodeToSeconds('01:00:00;00', 29.97) // Drop-frame timecodeToSeconds('01:00:00:00', 29.97) // Non-drop // Generating: Auto-selects based on duration at 29.97/59.94 fps secondsToTimecode(3600, 29.97) // '01:00:00;00' (≥1 min = drop-frame) secondsToTimecode(30, 29.97) // '00:00:30:00' (<1 min = non-drop) // Override auto-detection secondsToTimecode(3600, 29.97, false) // '01:00:00:00' (force non-drop) secondsToTimecode(30, 29.97, true) // '00:00:29;29' (force drop-frame)Converts seconds to timecode format.
secondsToTimecode( seconds: number, // Time in seconds frameRate: FrameRate, // 23.976, 24, 25, 29.97, 30, 50, 59.94, or 60 dropFrame?: boolean // Optional: true/false, auto-detects if omitted ): string // Returns "HH:MM:SS:FF" or "HH:MM:SS;FF"Converts timecode to seconds. Auto-detects drop-frame from semicolon separator.
timecodeToSeconds( timecode: string | number, // Timecode string or seconds frameRate?: FrameRate // Required for timecode strings ): number // Returns secondsFormats timecode without frames (HH:MM:SS).
shortTimecode( timecode: string | number, frameRate?: FrameRate ): string // Returns "HH:MM:SS"Validates timecode format and values.
validateTimecode('25:00:00:00', 25) // Returns: // { // valid: false, // errors: ['Hours cannot exceed 23'], // warnings: [], // format: 'non-drop', // components: undefined // }Checks if timecode uses drop-frame format (semicolon separator).
isDropFrameTimecode('01:00:00;00') // true isDropFrameTimecode('01:00:00:00') // falseChecks if frame rate supports drop-frame.
isDropFrameRate(29.97) // true isDropFrameRate(25) // falseimport { secondsToTimecode, timecodeToSeconds } from 'timecode-converter' // PAL (25 fps) secondsToTimecode(90, 25) // '00:01:30:00' timecodeToSeconds('00:01:30:00', 25) // 90 // NTSC (29.97 fps) with auto drop-frame secondsToTimecode(3600, 29.97) // '01:00:00;00' (auto drop-frame) secondsToTimecode(30, 29.97) // '00:00:30:00' (auto non-drop) // Film (24 fps) secondsToTimecode(3600, 24) // '01:00:00:00' timecodeToSeconds('01:00:00:00', 24) // 3600// Let auto-detection handle it const timecode = secondsToTimecode(durationInSeconds, 29.97) // Or be explicit const dropFrame = secondsToTimecode(3600, 29.97, true) // Force drop-frame const nonDrop = secondsToTimecode(3600, 29.97, false) // Force non-drop // Parsing handles both formats automatically timecodeToSeconds('01:00:00;00', 29.97) // Semicolon = drop-frame timecodeToSeconds('01:00:00:00', 29.97) // Colon = non-dropimport { validateTimecode } from 'timecode-converter' function processUserInput(timecode: string, fps: number) { const validation = validateTimecode(timecode, fps) if (!validation.valid) { throw new Error(validation.errors.join(', ')) } if (validation.warnings.length > 0) { console.warn('Warnings:', validation.warnings) } return timecodeToSeconds(timecode, fps) }import { timecodeToSeconds, secondsToTimecode, isDropFrameTimecode } from 'timecode-converter' function offsetTimecode(timecode: string, offsetSeconds: number, fps: number) { // Preserve drop-frame format through conversion const isDropFrame = isDropFrameTimecode(timecode) const seconds = timecodeToSeconds(timecode, fps) const newSeconds = seconds + offsetSeconds return secondsToTimecode(newSeconds, fps, isDropFrame) }| Frame Rate | Standard | Drop-Frame | Common Use |
|---|---|---|---|
| 23.976 | NTSC Film | No | Film transferred to video |
| 24 | Film | No | Cinema |
| 25 | PAL | No | European TV |
| 29.97 | NTSC | Yes* | American TV |
| 30 | NTSC | No | American TV (rare) |
| 50 | PAL | No | European HD |
| 59.94 | NTSC | Yes* | American HD |
| 60 | NTSC | No | American HD (rare) |
* Drop-frame is optional but recommended for broadcast accuracy
If you're upgrading from the original timecode-converter, see our Migration Guide for detailed instructions.
Key changes:
- Frame rate is now required (no more defaults)
- Full drop-frame timecode support
- New validation functions
- Improved precision and accuracy
- TypeScript types included
# Clone the repository git clone https://github.com/jordanburke/timecode-converter.git cd timecode-converter # Install dependencies pnpm install # Run tests pnpm test # Build the library pnpm build # Run tests in watch mode pnpm test:watchContributions are welcome! Please feel free to submit a Pull Request.
This is a complete TypeScript rewrite of the original timecode-converter, originally extracted from @bbc/react-transcript-editor, with original domain logic from @bevand10.
While this started as a fork, it has been completely rewritten with:
- Full TypeScript implementation
- SMPTE drop-frame support
- Smart auto-detection
- Comprehensive validation
- Modern tooling and testing
- Improved accuracy and precision
MIT