How it works
SMPTE timecode labels every frame with an address: hours, minutes, seconds and a frame
number, written HH:MM:SS:FF. The frame number by itself is unambiguous only
once you know the frame rate, because FF counts up to one less than that rate
and rolls over into the seconds field. This tool works from a single frame number as the
ground truth — a plain non-negative (or, for arithmetic results, possibly negative)
integer counting frames from zero — and converts it to and from the human
HH:MM:SS:FF form for whichever rate you have selected.
A short history, because it explains the drop-frame decision
Timecode predates digital editing by two decades. It was developed in the late 1960s so
that videotape machines — which, unlike film, have no sprocket holes or visible frame
edges to count by hand — could still be cued to an exact frame for editing. The
Society of Motion Picture and Television Engineers standardised the format, and it has
carried the SMPTE name ever since, even as the underlying hardware moved from two-inch
quadruplex videotape to file-based media with the timecode stored as metadata rather than
encoded in the picture. The current standard, ST 12-1, still specifies the same
HH:MM:SS:FF structure and the same drop-frame correction devised in the analog
era, because the arithmetic problem it solves — a frame rate that is not a clean
integer — never went away. It simply moved from NTSC broadcast video to the
29.97 and 59.94 fps options that survive inside modern digital cameras and editing
software for compatibility with that legacy.
Non-drop-frame arithmetic
For every rate that is a clean integer — 24, 25, 30, 50, 60 — and for the
non-drop-frame reading of 29.97 and 59.94, the conversion is the arithmetic you would expect:
the frame number is fps × (3600h + 60m + s) + f, and the inverse divides
that number back out with the usual carries. No frame numbers are ever skipped in this mode,
which is exactly why the displayed clock slowly disagrees with real elapsed time whenever the
true rate carries a /1.001 — see the drift explained below.
Drop-frame arithmetic
Drop-frame is the same underlying frame count with a different labelling rule layered on
top. At 29.97 fps DF, the frame numbers ;00 and ;01 are skipped at
the start of every minute except minutes divisible by ten; at 59.94 fps DF, the numbers
;00–;03 are skipped under the same rule. This tool implements
the standard closed-form formula for that skip — no per-frame loop, so a conversion at
any timecode, however large, is instant:
frameNumber = nominal×3600×h + nominal×60×m + nominal×s + f
− dropFrames × (totalMinutes − floor(totalMinutes / 10))
where totalMinutes = 60h + m, nominal is 30 or 60, and
dropFrames is 2 or 4. The inverse (frame number back to timecode) adds the
skipped count back in, based on how many whole and partial ten-minute blocks the frame
number has passed through.
Verifying the arithmetic independently
A closed-form formula is fast, but a formula that has a subtle sign error can look correct
for months before someone hits the specific timecode where it fails. So this tool’s
logic was checked against a second implementation built a completely different way: instead
of a formula, a frame-by-frame simulator that starts at frame zero and steps forward one
frame at a time, applying the drop rule directly — “if this new minute is not a
multiple of ten, jump the frame field from 0 straight to the drop count” — the
same plain-language rule a human would follow with a physical counter. The two
implementations were run against each other across 2,529,504 individual frames,
spanning four continuous hours each at 29.97 and 59.94 drop-frame plus sanity ranges at every
other rate, with zero disagreements. Every required reference value — including
00:00:59;29 + 1 frame = 00:01:00;02, the minute-ten exemption, and the exact
frame counts for one hour at each rate — matched exactly. See
the drop-frame guide for the full worked derivation.
Real time and the drift
29.97 fps is exactly 30000/1001 frames per second, not 30 —
about 0.1% slower. Over one real hour, that difference adds up to
3.6 seconds. A non-drop-frame clock, which counts every second as exactly 30
frames, drifts behind real elapsed time by that much per hour. A drop-frame clock corrects
for it by skipping frame numbers, so the displayed HH:MM:SS stays within a
couple of frames of real elapsed time indefinitely. See 29.97 vs
30 for the arithmetic behind that 3.6-second figure.
Why broadcasters and post houses still care
Modern cameras and editing systems increasingly default to exact rates — 24, 25, 30 — for anything destined for streaming or the web, and 29.97/59.94 can feel like a historical footnote. It is not, in two specific places. First, delivery specifications for broadcast and for many streaming platforms in NTSC-legacy territories (North America, Japan, parts of Latin America) still require 29.97 or 59.94 masters with correctly labelled drop-frame timecode, because downstream broadcast automation and captioning systems key off it. A QC report that flags “timecode discontinuity” is very often a drop-frame label computed the wrong way, not a real gap in the footage. Second, any project that mixes material shot at 23.976 or 29.97 with a sequence timeline at a different rate needs someone to reason about what a given frame count becomes after a conform — exactly what the Rate Conversion tab above is for, short of actually performing that conform.
Escaping and safety
Every value that reaches this page — the timecode you type, the frame number, every
result — is written with textContent, never assembled into an HTML string.
There is nothing on this page that calls eval or builds markup from your input.
Worked examples
1. The frame that crosses a minute boundary at 29.97 DF
Select 29.97 fps DF, enter 00:00:59;29 in the Timecode
field on the Timecode ↔ Frame tab, note the frame number, then switch to Arithmetic
and add 1 frame.
00:00:59;29 +1 frame → 00:01:00;02
The clock does not read 00:01:00;00. Minute 1 is not a multiple of ten, so
frame numbers ;00 and ;01 are skipped the instant that minute
begins — the very next frame after ;29 is labelled ;02.
Nothing was lost: the frame after 59;29 exists, is played, and is simply not called ;00.
2. Minute ten is exempt
Same rate, one minute boundary later:
00:09:59;29 +1 frame → 00:10:00;00
This time the label does land on ;00, because minute 10 is a
multiple of ten and the drop rule specifically excludes those minutes. Dropping two frame
numbers every single minute, with no exemption, would overcorrect the drift; leaving one
minute in ten alone brings the average back in line with the true 30000/1001 rate. This is
also why ten minutes of 29.97 DF timecode is 17,982 frames, not a round
18,000 — nine minutes drop 2 numbers each (18 total) and the tenth drops none.
3. One hour, three ways
Enter 01:00:00;00 on the Timecode ↔ Frame tab under each rate in turn
and read off the frame number:
29.97 fps DF 01:00:00;00 → frame 107,892
30 fps NDF 01:00:00:00 → frame 108,000
59.94 fps DF 01:00:00;00 → frame 215,784
Switch to the Timecode ↔ Real Time tab with the same values and the point of all of this becomes visible: 107,892 frames at the true 29.97 rate is 3,599.9964 real seconds — 3.6 milliseconds off a clean hour, an error of one three-hundred-thousandth. The drop-frame label was built specifically to make that true. Compare it against 30 fps NDF’s 108,000 frames read at the true 29.97 rate on the 29.97 vs 30 page: 3,603.6 real seconds, 3.6 seconds adrift — a thousand times worse.
4. Duration between two timecodes
On the Arithmetic tab, choose Duration between two, and at
29.97 fps DF enter Timecode A as 01:00:00;00 and Timecode B
as 01:15:32;10. The tool reports the frame difference, the duration re-expressed
as its own timecode, and the exact real-time length — the calculation a clip
length, an EDL duration, or a delivery-spec check all come down to. Because drop-frame
timecode already tracks real time, that duration in seconds is accurate directly; the same
subtraction under non-drop-frame timecode would need the 3.6-second-per-hour correction
applied by hand.
5. Reinterpreting a frame at another rate
On the Rate Conversion tab, set From to 23.976 fps, To
to 29.97 fps DF, and enter 01:00:00:00. The tool reports what frame index
86,400 (one hour at 23.976) reads as under a 29.97 DF clock — a shorter timecode,
because the same count of frames represents less real time at a higher rate. This is a
relabelling, not a conform: it tells you what the number becomes, not how to actually
retime the picture from 23.976 to 29.97, which is a resampling operation an edit or
transcode application performs on the frames themselves.
Frequently asked questions
What is SMPTE timecode?
SMPTE timecode is a way of labelling every frame of video or film with an address in
the form HH:MM:SS:FF — hours, minutes, seconds and a frame number
within that second. It was standardised by the Society of Motion Picture and Television
Engineers so that different machines, edit systems and tape formats could refer to the
exact same frame unambiguously. The standard in force today is
SMPTE ST 12-1,
the successor to the original 1970s EBU/SMPTE time-and-control-code specification.
What is the difference between drop-frame and non-drop-frame timecode?
Both count video at the same true frame rate. The difference is only in how the
HH:MM:SS:FF label is assigned. Non-drop-frame (NDF) numbers frames as if the
rate were a clean integer — 30 or 60 — so the displayed clock slowly falls
behind real elapsed time when the true rate is actually 29.97 or 59.94. Drop-frame (DF)
periodically skips certain frame numbers so the displayed clock tracks real time
closely.
No video frame is ever removed in either case; only the label changes. See the full drop-frame guide for the mechanics.
Why does 29.97 fps exist instead of a clean 30?
When color was added to the American NTSC television standard in 1953, the color subcarrier had to be interleaved with the existing black-and-white signal and the audio carrier without producing visible interference patterns. The fix engineers landed on was a very small rate change — multiplying the original 30 fps by 1000/1001 — which gave 29.97 fps exactly (30000/1001). The same 1000/1001 relationship carries through to 59.94 for high-frame-rate NTSC-family formats.
It is a frequency-engineering artifact from the analog color era, not an arbitrary round number. See 29.97 vs 30 for the full arithmetic and further reading.
Does drop-frame timecode actually lose video frames?
No — this is the single most common misunderstanding about it. Drop-frame
timecode drops frame numbers, never actual frames of picture or sound.
Every frame that was captured is still there, in order, played back at the same rate. All
that changes is which HH:MM:SS:FF label a given frame is assigned,
specifically to keep that label tracking real elapsed clock time.
Which frame numbers get dropped, and why not every tenth minute?
At 29.97 fps drop-frame, the frame numbers ;00 and ;01 are
skipped at the start of every minute except minutes divisible by ten. At 59.94 fps
drop-frame, four numbers (;00 through ;03) are skipped under the
same rule.
The exemption every tenth minute exists because the correction is slightly too large otherwise: dropping 2 frame numbers every single minute would overcorrect the drift, so one minute in ten is left alone to bring the average back in line with the true 30000/1001 rate. This is exactly why 10 minutes of 29.97 drop-frame timecode is 17,982 frames rather than a round 18,000.
How do I know if my footage is drop-frame or non-drop-frame?
Look at the separator before the frames field on a burned-in timecode or in your
NLE’s timeline display: a semicolon (or sometimes a period), as in
01:00:00;00, conventionally marks drop-frame; a colon, as in
01:00:00:00, marks non-drop-frame.
That said, the separator is a convention some tools get sloppy about, so the safer check is the project or sequence frame-rate setting itself — drop-frame only exists as an option at 29.97 and 59.94.
Can I convert between drop-frame and non-drop-frame directly?
Yes, provided the true frame rate is the same on both sides — 29.97 DF and 29.97 NDF describe the same underlying frame rate, just labelled two different ways. Convert the DF timecode to a frame number, then read that same frame number back out under the NDF labelling rule (or the reverse).
The Rate Conversion tab above does exactly this: pick 29.97 fps DF and 29.97 fps NDF as
the two sides and the frame number itself never changes, only the
HH:MM:SS:FF text.
What does frame-rate conversion actually do here, and what does it not do?
The Rate Conversion tab takes a frame index and reinterprets that same integer under a different rate’s timebase — it relabels the number, nothing more. It does not resample, retime, add or remove 2:3 pulldown, or touch a single sample of picture or audio.
Real conforming between genuinely different rates (23.976 to 29.97, for instance) is a picture and sound operation done in an editing or transcoding application; this tool only tells you what a given frame count reads as under another rate’s clock, which is useful for reasoning about a conform, not a substitute for doing it.
Why do 24 fps and 25 fps have no drop-frame option?
Drop-frame timecode exists to correct a specific NTSC-family drift: the true rate (30000/1001 or 60000/1001) is very slightly slower than the round number used to count frames. 24 fps (cinema) and 25 fps (PAL/SECAM television) are both exact integers with no such fractional drift, so there is nothing for a drop-frame scheme to correct.
23.976 fps — 24 divided by 1.001, used when 24 fps material is played back on NTSC-rate equipment — does carry the same fractional relationship as 29.97 and 59.94, but no SMPTE drop-frame standard was ever defined for it, so it is conventionally handled as non-drop-frame with the small drift left unaddressed or corrected elsewhere in the pipeline.
What happens if I enter a frame number that doesn’t exist?
You get a specific message naming the problem, never a blank result or
NaN. Typing frame 30 at 30 fps reports that frames run 00–29
at that rate; typing a dropped frame number in a non-exempt minute at a drop-frame rate
— 00:01:00;00, for instance — reports that ;00 does not exist in
minute 00:01 at 29.97 DF and explains why.
Does this account for video fields, for interlaced formats?
No — this tool works entirely in whole frames. Interlaced video splits each frame into two fields, and some equipment can address individual fields, but SMPTE timecode itself is a frame-level address; the field within a frame is a separate, lower-level concern handled by the playback or capture hardware, not by the timecode number.
What is the largest timecode this handles?
Frame numbers are ordinary JavaScript integers, exact up to 253 − 1 (about 9 quadrillion). At 59.94 fps that is well over four billion years of continuous timecode, so the practical limit in this tool is not the frame count — it is that most equipment and file formats wrap the hours field at 24, and this tool does not enforce that wrap, so it will show hour values above 23 for arithmetic results and durations rather than silently rolling them over.
Is any of my timecode data sent to a server?
No. Every parse, every frame calculation and every arithmetic operation runs as JavaScript inside your browser tab. There is no upload endpoint and nothing here that could send a timecode anywhere — what you type never leaves your device. You can save this page and use it with the network disconnected.
Use cases and limitations
What people use this for
- Reading an EDL or a burned-in timecode. Converting a timecode you can see on screen or in a log into a frame number for a cue sheet, a VFX shot list, or a bug report to an editor.
- Checking drop-frame arithmetic by hand. Confirming what a specific frame addition or subtraction should produce before trusting an NLE’s own display, or explaining a colleague’s “why did the timecode jump” question.
- Working out a clip or programme duration. Subtracting two timecodes correctly across a drop-frame boundary, including the real-time length for a delivery spec that measures duration in seconds rather than frames.
- Reasoning about a frame-rate conform. Seeing what a given frame count would read as under a different rate before commissioning the actual retime in an editing application.
- Learning the mechanics. The worked examples and the drop-frame guide exist because the algorithm is genuinely stateful and easy to get subtly wrong, and most explanations either skip the minute-ten exemption or get the sign backwards.
- Cross-checking a QC report. A delivery QC tool that flags a “timecode discontinuity” on a drop-frame master is often just reporting a label computed the wrong way rather than an actual gap; recomputing the expected frame count by hand here settles the question quickly.
- Sanity-checking scripting and pipeline code. If you are writing your own timecode handling in an automation script, ingest tool or render farm job, the test vectors and the reference implementation described below are a fast way to check a new implementation against known-correct values before trusting it with real media.
What it deliberately does not do
- Read or write video files. This is a calculator for the numbers, not a tool that opens footage, reads embedded timecode metadata, or touches a frame of picture.
- Conform or retime. Frame-rate conversion here relabels a frame index; it does not resample audio, interpolate frames, or add/remove pulldown. That is the job of an editing or transcoding application.
- Model timecode discontinuities on tape or in a multi-clip sequence. Real-world footage can have timecode breaks, resets, or non-continuous reels; this tool assumes a single continuous count from a starting timecode.
- Invent a drop-frame rule for rates that don’t have one. 24 fps, 25 fps, and plain integer rates simply have no DF option, by design — see the FAQ above.
Honest limitations
Hours are accepted as any whole number for arithmetic and duration purposes (useful for a
programme longer than a day, or for a running total), but the practical convention on most
equipment is 00–23 before the count wraps. Frame-rate conversion is a pure relabelling
of an integer frame index and says nothing about how a real conform should handle field
order, 2:3 pulldown cadence, or audio sample-rate conversion — those decisions depend
on your specific footage and pipeline, not on arithmetic alone. There is also no facility
here for reading timecode embedded in a media file’s metadata (an mdta
timecode track, an LTC audio channel, a vertical-interval VITC signal) — you supply the
timecode as text, and the tool works entirely from that. If your footage’s frame rate
is not one of the ten listed, or if it uses a non-standard drop pattern occasionally seen in
older equipment, the arithmetic here will not match it; the ten rates covered are the ones
defined by SMPTE ST 12-1 and its predecessors and used by essentially all current cameras,
editing systems and delivery specifications.
More on timecode
- What is drop-frame timecode?The full mechanics, the minute-ten exemption, and why it exists
- 29.97 fps vs 30 fpsWhere the 1000/1001 ratio comes from and what it costs you
- Frames to timecodeConverting a raw frame count into HH:MM:SS:FF, worked through
- About this toolWhy it’s built this way, and how the arithmetic was verified