How SMPTE timecode works
A SMPTE timecode labels a specific frame as HH:MM:SS:FF at a chosen frame rate. The first three fields are clock-style; the last is the frame index within the second.
Non-drop-frame (NDF)
NDF counts every frame sequentially with no skips - the labels are a pure counter.
total_frames = (HH × 3600 + MM × 60 + SS) × fps_int + FF
seconds = total_frames / fps_real
For 29.97 NDF the labels tick at 30 per second but real time only advances at 29.97/sec, so the labels drift ahead by roughly 3.6 seconds per hour. This drift is exactly what drop-frame timecode corrects.
Drop-frame (DF) - 29.97 and 59.94 only
Drop-frame skips the first two frame numbers at the start of every minute except every 10th minute. So at 29.97 DF, after 00:00:59;29 the next frame is 00:01:00;02 (two numbers skipped), and the minute 10 boundary skips nothing (00:09:59;29 → 00:10:00;00).
drops_in_hh_mm_ss = 2 × (total_minutes - floor(total_minutes / 10))
total_frames = (HH × 3600 + MM × 60 + SS) × 30 + FF - drops
For 59.94 DF the same rule applies but 4 frame numbers are skipped (00, 01, 02, 03) instead of 2.
Worked example - 29.97 drop-frame
- The timecode that immediately follows
00:00:59;29is00:01:00;02- frames;00and;01are skipped. - The label
00:01:00;02is the 1,800th frame (frame number 1799 zero-indexed), matching the 1,800 frames played in 60.06 real seconds. - The timecode that follows
00:09:59;29is00:10:00;00- frames;00and;01are not skipped, because 10 is a multiple of 10. - Over a full hour, drop-frame skips 9 × 6 × 2 = 108 frame numbers, exactly compensating for the 3.6-second drift NDF would produce.
Frame rate reference
| Frame rate | Real fps | Counter fps | Drop-frame? | Separator | Use case |
|---|---|---|---|---|---|
| 23.976 | 24000/1001 | 24 | NDF only | : | Film, 23.976p video |
| 24 | 24 | 24 | NDF only | : | Digital cinema |
| 25 | 25 | 25 | NDF only | : | PAL television |
| 29.97 NDF | 30000/1001 | 30 | No | : | NTSC (drifts vs real-time) |
| 29.97 DF | 30000/1001 | 30 | Yes, drop 2/min | ; | NTSC broadcast (sync to wall-clock) |
| 30 | 30 | 30 | NDF only | : | Web video, web cinema |
| 50 | 50 | 50 | NDF only | : | PAL high-frame-rate |
| 59.94 NDF | 60000/1001 | 60 | No | : | NTSC HFR (drifts) |
| 59.94 DF | 60000/1001 | 60 | Yes, drop 4/min | ; | NTSC HFR broadcast |
| 60 | 60 | 60 | NDF only | : | Web HFR |
Frequently Asked Questions
What is drop-frame timecode?
Drop-frame is the convention for 29.97/59.94 fps NTSC video that keeps the labeled clock aligned with real wall-clock time. NTSC plays at 30000/1001 fps, so a 30-fps counter would drift ~3.6 s per hour. Drop-frame skips the first two frame numbers at the start of every minute except every 10th minute (108 skipped per hour at 29.97), which compensates exactly.
How many frames are in a minute at 29.97 fps?
At 29.97 NDF, a minute contains 1,800 frame labels (30 × 60). At 29.97 DF the labels still cover 1,800 frame positions per minute, but at the start of 9 out of every 10 minutes two frame numbers are skipped, so only 1,798 numbered frames appear in those minutes.
How do I convert timecode to seconds?
Convert the timecode to a total frame count, then divide by the real frame rate. For 29.97 NDF: frames = (HH×3600 + MM×60 + SS)×30 + FF, then seconds = frames / 29.97. For 29.97 DF subtract 2 dropped frames for every minute that is not a multiple of 10 before dividing.
What is the difference between drop-frame and non-drop-frame?
NDF counts every frame sequentially - labels drift from real time at NTSC rates. DF skips two frame numbers at the start of 9 out of every 10 minutes so the labels stay synced to wall-clock. DF timecodes are written with a semicolon (00:01:00;02), NDF with a colon (00:01:00:00).