Skip to main content
SubtitleMatrix

Snap Subtitles to Frames

TimingAlign to a reference track
Or paste subtitle text

Options

Every cue boundary is moved to the nearest frame at this rate, so at 25 fps 00:00:02,010 becomes 00:00:02,000 and 00:00:02,030 becomes 00:00:02,040. A boundary exactly halfway between two frames rounds up, so 00:00:02,020 becomes 00:00:02,040. Nothing is scaled: the timeline keeps its length and the boundaries just land on frames, so each cue's length can change by up to half a frame either way. This is not the file's declared frame rate — it only decides where the boundaries end up in the output.

Which frame rate the timings are counted in. On the format pages this is what MicroDVD needs, because it stores timing as frame numbers. On the frame rate pages it is the rate the file was timed against — the version the subtitles were made for — and the page's second box takes the rate of the video you are going to use them with. 23.976, 24, 25, 29.97, 30, 50, 59.94 and 60 are the common ones. Getting it wrong shifts the whole timeline, and on the frame rate pages it shifts it by a ratio rather than by a fixed amount.

This page moves every cue boundary onto the nearest frame of a frame rate you choose. It does not change the speed of anything: the timeline keeps its length, the cue order stays as it was, and what changes is only where each boundary sits — 00:00:02,010 at 25 frames a second becomes 00:00:02,000, and 00:00:02,030 becomes 00:00:02,040. Each cue's length can therefore change by up to half a frame in either direction, which is the trade this page makes on purpose.

The job it does is taking a decision away from the player. Subtitles are stored in milliseconds, but most players and burning tools work in frames, so a boundary that falls between two frames has to be rounded by whoever draws it — and different software rounds it differently. One player shows the line a frame early, another a frame late, and the same file looks slightly out on two machines. Snapping once, here, makes that decision yours and makes it once: after this, every boundary is a frame boundary, and every tool that reads the file agrees.

It is not a frame rate conversion. Changing subtitles from 23.976 to 25 multiplies the whole timeline by a ratio so that the cues still fit the video, and that is a different page in a different group. This page leaves the video out of it entirely: if the file is already correct and you only want the boundaries on frames, snap it; if it is wrong against the video, the ratio has to change first.

Two frame-rate boxes appear because they answer different questions. One is the rate the file is read with, which frame-number formats such as MicroDVD need in order to be understood at all. The other is the rate to snap to. On a file that declares its own rate they will usually be the same number, and mixing them up is quiet — the output is still frame-accurate, just on the wrong grid. Everything runs in this browser tab, with no upload, on SRT, WebVTT, ASS, SSA, SBV, SAMI, MicroDVD, TTML, JSON and CSV alike.

Examples

Every boundary lands on a frame

Input

1
00:00:02,020 --> 00:00:04,030
Hello there.

2
00:00:07,010 --> 00:00:09,040
Second line.

Output

1
00:00:02,040 --> 00:00:04,040
Hello there.

2
00:00:07,000 --> 00:00:09,040
Second line.

At 25 frames a second the boundaries belong on multiples of 40 ms. 02,020 is exactly halfway between two of them and rounds up to 02,040; 04,030 comes up to 04,040; 07,010 goes back to 07,000. Nothing was scaled — the second cue is still about two seconds long and the gap between the two is unchanged to the frame — but each cue's own length moved a little: 2010 ms and 2030 ms came out as 2000 ms and 2040 ms.

A cue shorter than a frame

Input

1
00:00:04,000 --> 00:00:04,010
Squeezed.

2
00:00:06,010 --> 00:00:08,010
A normal one.

Output

2
00:00:06,000 --> 00:00:08,000
A normal one.

The 10 ms cue has both of its boundaries rounding to frame 100, so snapping would leave it with the same time at each end — and a cue that ends where it starts cannot be shown. It is dropped and counted rather than stretched to one frame, because inventing a length would be putting a subtitle on screen that the file never asked for. At 25 frames a second it takes a cue shorter than 20 ms to reach this; the second cue is twenty times longer and behaves as usual.

A fractional frame rate cannot leave lengths alone

Input

1
00:00:01,000 --> 00:00:03,000
Hello there.

Output

1
00:00:01,001 --> 00:00:03,003
Hello there.

23.976 frames a second is not a whole number of milliseconds per frame, so no round second is a frame boundary at all and both edges move: a cue that ran exactly 2000 ms comes out 2002 ms long. Every boundary is still on a frame, which is what the page promises, but the round numbers the source was written with are gone. This is worth seeing before snapping a file to 23.976 or 29.97 and expecting the timings to come back unchanged.

Frequently asked questions

What does snapping to frames do that converting the frame rate does not?

Converting changes how long the timeline is; snapping changes only where the boundaries fall on it. Converting subtitles from 24 to 25 frames a second multiplies every timestamp by 0.96 so they still fit the video, and a cue that was two seconds long becomes 1.92. Snapping leaves that two seconds at two seconds and moves its edges onto the nearest frame, changing them by less than half a frame each.

Will snapping make my subtitles line up with a video running at a different frame rate?

No. This page never looks at the video and never changes the length of the timeline, so a file that is out because the video runs at a different rate stays exactly as far out after it. Work out the ratio first — that is what the frame rate conversion pages are for — and snap afterwards if the tool you are delivering to needs boundaries on frames.

How much can a cue's length change when it is snapped?

Up to half a frame at each edge, so up to a whole frame in total, and never more. At 25 frames a second that is at most 40 ms on a cue, 20 ms per boundary. At 23.976 or 29.97 there is no whole number of milliseconds per frame, so even a cue that starts and ends on round values moves: a two-second cue becomes 2002 ms.

I ran the page twice and the second run changed nothing. Is that right?

Yes, and it is what makes the page safe to leave in a batch. Once every boundary is on a frame, the nearest frame to a boundary is that boundary, so a second run returns the file byte for byte. If you are checking a delivery, that also means a file that changes on a second pass was not fully snapped the first time — which should not happen, but it is a cheap test.

Can a subtitle disappear when it is snapped?

Only if it is shorter than half a frame, in which case both its boundaries round to the same frame and there is no cue left to write. At 25 frames a second that means anything under 20 ms, which no real subtitle is; the page counts what it drops, so the report is where to look rather than the download.

Should I snap to the frame rate the file itself declares?

Not automatically — the declaration says how to read frame numbers in the file, and the snap rate says where boundaries go in the output. They are the same number in most deliveries. They differ when you are preparing a file for a tool that works at another rate, and choosing the declared rate there is the quiet mistake: the output is still frame-accurate, on the grid nobody asked for.

Related tools