Move every subtitle cue earlier or later
Moves every cue in an SRT or WebVTT subtitle file by one constant, millisecond-precise offset. It changes recognised timing lines while keeping cue text, identifiers, settings, comments and surviving line endings intact.
A UTF-8 SubRip (.srt) or WebVTT (.vtt) file up to 20 MB. The file is read only in this tab.
How it works
What this works out
A subtitle sidecar is a sequence of text cues placed on a media timeline. When every caption appears the same amount too soon or too late, the wording is not wrong and the individual cue durations are not wrong — the complete timeline has one constant offset.
This tool measures that offset in whole milliseconds and writes a corrected
.srt or .vtt artifact. The media file is not needed because the operation
is entirely inside the subtitle timeline: every recognised start and end gets
the same signed change.
The method
The arithmetic is deliberately small:
offset_ms = round(offset_seconds × 1,000)
Later: new_time_ms = old_time_ms + offset_ms
Earlier: new_time_ms = old_time_ms - offset_ms
Applying the same value to both ends preserves a cue’s duration. A cue from
00:00:01,250 to 00:00:03,500 lasts 2.250 seconds; after a two-second delay
it runs from 00:00:03,250 to 00:00:05,500 and still lasts 2.250 seconds.
The relationship between cues is preserved too: if two cues overlap by half a
second before the shift, they overlap by half a second afterwards.
What requires care is recognising where that arithmetic belongs. A blind
search for timestamp-shaped text would also change times written in dialogue,
comments or CSS. The file is therefore walked as blank-line-separated blocks.
For SRT, a cue timing is the first line or the line after its numeric counter.
For WebVTT, it is the first line or the line after an optional cue identifier;
the WEBVTT header and NOTE, STYLE and REGION blocks are structural and
are never treated as cues.
The complete timing line must match before anything changes. SRT uses a comma before milliseconds:
00:01:02,000 --> 00:01:04,250
WebVTT uses a full stop, may omit zero hours, and can carry settings after the end:
01:02.000 --> 01:04.250 position:50% align:middle
The W3C grammar requires whitespace around WebVTT’s -->, an end later than
the start, and cues ordered by their start time. Those constraints are checked
instead of quietly rewriting a line that only resembles a cue.
Before you read on
A subtitle appears at 00:01.250, but its spoken word begins at 00:03.250. Which change aligns it?
Move it later by two seconds. Later adds 2,000 milliseconds to the start and end together, so 00:01.250 becomes 00:03.250 without changing how long the subtitle remains visible. Earlier is for the opposite symptom: text that appears after the matching speech.
What happens at the start of the timeline
Adding a delay can never make a timestamp negative. Subtracting one can. The file format has no representation for a cue at minus half a second, so the tool makes that boundary visible instead of wrapping the value or writing an invalid minus sign.
- If the shifted end is at or before zero, none of the cue can appear and the cue is removed.
- If the shifted start is negative but the end is still positive, Clamp its start to 00:00 keeps the visible remainder and shortens only that cue.
- Remove the whole cue discards a crossing cue instead. That is useful when its opening words belong to content that was cut away.
Numeric SRT counters and WebVTT identifiers are not renumbered after a removal. They can be referenced outside the file, and a gap is safer than silently changing those references.
A worked example
interview.srt contains two cues:
1
00:00:01,250 --> 00:00:03,500
The first subtitle.
2
00:01:02,000 --> 00:01:04,250
The second subtitle.
With Later and 2 seconds, interview-shifted.srt is:
1
00:00:03,250 --> 00:00:05,500
The first subtitle.
2
00:01:04,000 --> 00:01:06,250
The second subtitle.
| Reading | Value |
|---|---|
| Cues shifted | 2 |
| Cues removed | 0 |
| Subtitle format | SubRip (SRT) |
| Offset applied | 2.000 seconds |
The formula test asserts the complete output byte for byte, including the CRLF line endings, filename, MIME type and all four readings. A separate test covers WebVTT identifiers, cue settings, comments and style blocks, and boundary tests cover clamping, removal, the one-hour transition, encoding errors, cancellation and malformed timing.
SRT and WebVTT are similar, not interchangeable
The Library of Congress describes SRT as a simple text format built from a counter, start and end, subtitle text and a blank separator. It is widely implemented but not formally standardised, and its historic character encoding is not self-declaring. That is why this tool accepts the common timing grammar but refuses to guess non-UTF-8 text.
WebVTT is specified for HTML text tracks. Its first line is the WEBVTT magic
header, its MIME type is text/vtt, its timestamps use a dot, and cues may have
identifiers and positioning settings. Comments and style or region blocks are
also part of the document. The output stays in the input format; shifting is not
conversion, so an SRT remains SRT and a WebVTT file remains WebVTT.
What it does not do
It does not stretch or compress a timeline. If a caption is one second late at the beginning and six seconds late at the end, use a resynchronisation workflow that maps two known points and rescales every timestamp. One constant offset would only move where the growing error begins.
It also does not modify embedded subtitle tracks inside a video container, and it does not inspect the media to discover the offset automatically. The input is the plain-text sidecar file. If the mismatch began because you trim a WAV file, use the exact amount removed as the subtitle offset; if the subtitle text itself needs cleaning, sort lines and other generic text operations are deliberately a separate job.
WebVTT cue payloads can contain inline timestamp tags for karaoke-like word timing. Those inner times are absolute points inside the outer cue. The tool refuses such a cue with an explanation: moving only the outer pair would leave an invalid file, while changing every possible payload construct belongs in a dedicated WebVTT editor rather than a constant-offset shifter.
How it is done
- Read the file as UTF-8 in this browser tab. Preserve an existing UTF-8 byte-order mark and each line ending; refuse UTF-16, invalid UTF-8 and binary input rather than guessing an encoding and damaging subtitle text.
- Treat a WEBVTT magic header as WebVTT and an accepted file without that header as SubRip. A file named .vtt is refused when the required WEBVTT first line is missing.
- Walk blank-line-separated blocks. Preserve WebVTT header, NOTE, STYLE and REGION blocks; recognise a cue only when one of its first two lines matches that format's complete start-arrow-end grammar.
- Parse each start and end into an integer number of milliseconds and require the end to be later than the start. Round the requested offset to one millisecond, then add it for Later or subtract it for Earlier.
- When an earlier shift puts a whole cue at or before zero, remove it because no negative playback time exists. When only the start crosses zero, either clamp the start to zero or remove the cue, exactly as selected.
- Write only the recognised timing line back in the source format. Preserve cue numbers, identifiers, payload text, WebVTT cue settings, structural blocks, a UTF-8 marker and the line endings of every surviving line, then offer the complete file for download.
What it assumes
- One constant offset applies to the whole file. If captions are aligned at the start and increasingly wrong later, that is drift or a playback-speed mismatch and cannot be repaired by adding one number everywhere.
- The offset is entered in seconds and rounded once to the nearest millisecond, because both supported file formats physically store three decimal digits. Later is positive and Earlier is negative in the result panel.
- SubRip timing is hours:minutes:seconds,milliseconds around the --> arrow. Numeric cue counters, including the compact form where the counter shares the timing line, are preserved and are not renumbered when an early cue is removed.
- WebVTT requires a WEBVTT first line, uses a full stop before milliseconds and may omit the hours component while it is zero. Existing hours notation is retained, and hours are added if a shifted timestamp crosses 60 minutes.
- WebVTT NOTE, STYLE, REGION, cue identifiers and settings are kept byte for byte apart from their surviving line endings. A cue containing an inline WebVTT timestamp tag is refused because changing only its outer times would corrupt karaoke-style internal timing.
- Cues may overlap before or after the shift; applying one offset preserves that relationship. This tool validates timing syntax and direction but does not decide whether an overlap was intended.
- Input is capped at 20 MB and 250,000 cues. The worker yields while scanning a long file so progress and Cancel remain responsive.
Common questions
Is the subtitle file uploaded while its timestamps are changed?
No. The file is decoded, checked and rewritten inside a worker in this browser tab. The generated browser test loads a real subtitle file and fails if using the tool sends a request away from this site.
What does moving subtitles later by two seconds do?
It adds exactly 2,000 milliseconds to every recognised cue start and end. A cue from 00:01.250 to 00:03.500 therefore becomes 00:03.250 to 00:05.500 without changing its duration or text.
Why did an early subtitle start at zero or disappear?
Media time cannot be negative. A cue shifted wholly to zero or earlier is removed; if only its start crosses zero, the default keeps the visible remainder from 00:00, while the advanced setting can remove the whole cue instead.
Are WebVTT cue positions, comments and styles preserved?
Yes. Cue settings after the end time and separate NOTE, STYLE and REGION blocks are carried through unchanged. The tool changes recognised outer timing lines and refuses inline timestamp tags rather than editing only part of a more complex cue.
Why was a subtitle in an older text encoding refused?
SRT has historically been saved in several code pages, and there is no reliable way to infer all of them from the bytes alone. Guessing could silently change names or dialogue, so this tool accepts UTF-8 and asks you to re-save UTF-16 or another encoding first.
Will a constant subtitle offset repair frame-rate drift?
No. An offset corrects the same early or late error at every point. When the difference grows over time, the timestamps need rescaling against the correct duration or frame rate rather than the same number added to each cue.