Modern TypeScript library for broadcast timecode conversions with full SMPTE drop-frame support
npm install timecode-converterA 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
``bash`
npm install timecode-converteror
pnpm add timecode-converteror
yarn add timecode-converter
`typescript
import { 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:
`typescript
// 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)
`
#### secondsToTimecode(seconds, frameRate, dropFrame?)
Converts seconds to timecode format.
`typescript`
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"
#### timecodeToSeconds(timecode, frameRate?)
Converts timecode to seconds. Auto-detects drop-frame from semicolon separator.
`typescript`
timecodeToSeconds(
timecode: string | number, // Timecode string or seconds
frameRate?: FrameRate // Required for timecode strings
): number // Returns seconds
#### shortTimecode(timecode, frameRate?)
Formats timecode without frames (HH:MM:SS).
`typescript`
shortTimecode(
timecode: string | number,
frameRate?: FrameRate
): string // Returns "HH:MM:SS"
#### validateTimecode(timecode, frameRate?)
Validates timecode format and values.
`typescript`
validateTimecode('25:00:00:00', 25)
// Returns:
// {
// valid: false,
// errors: ['Hours cannot exceed 23'],
// warnings: [],
// format: 'non-drop',
// components: undefined
// }
#### isDropFrameTimecode(timecode)
Checks if timecode uses drop-frame format (semicolon separator).
`typescript`
isDropFrameTimecode('01:00:00;00') // true
isDropFrameTimecode('01:00:00:00') // false
#### isDropFrameRate(frameRate)
Checks if frame rate supports drop-frame.
`typescript`
isDropFrameRate(29.97) // true
isDropFrameRate(25) // false
`typescript
import { 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
`
`typescript
// 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-drop
`
`typescript
import { 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)
}
`
`typescript
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
`bashClone the repository
git clone https://github.com/jordanburke/timecode-converter.git
cd timecode-converter
Contributions 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