Subtitle Timing in the Browser: Shift Cues, Repair Overlaps and Export SRT or WebVTT
I work on OnePassApps, so this is our own app and our own build, and every number below was measured in it on 6 November 2026.
Subtitle files rarely break in interesting ways. A translation arrives with its cues out of order. A video was re-cut, so every cue now starts two seconds late. Two lines were typed on top of each other. One cue has the same start and end time, so it is never on screen at all.
The Subtitle Workbench in our app directory takes an SRT or WebVTT file, reports those problems per cue, lets you shift and repair the timings, and exports a new file. The site's own description of it reads: "Convert existing SRT and WebVTT files, shift or repair timings, validate cues and export subtitle batches locally. Does not transcribe audio."
You can open it here: Subtitle Workbench. The step-by-step version is in the app guides.
The file I tested with
I pasted a hand-built four-cue SRT with one defect of each kind: the cues were listed in the wrong order, one cue had zero duration, and two cues overlapped. It is 214 bytes, and the source chip read "4 cues · 214 B · 1 error".
Here is what the panel said before anything was changed:
| Cue | In | Out | Length | Line | What the panel reported |
|---|---|---|---|---|---|
| 01 | 00:00:05,000 | 00:00:07,000 | 2.0 s | Later cue listed first | Cue overlaps another cue. Overlaps may be intentional. |
| 02 | 00:00:01,000 | 00:00:02,000 | 1.0 s | Earlier cue listed second | Cues are out of chronological order. |
| 03 | 00:00:08,000 | 00:00:08,000 | 0.0 s | Zero duration cue | Error: End must be after start. Enable the duration repair or edit the source. |
| 04 | 00:00:03,500 | 00:00:05,500 | 2.0 s | Overlapping cue | Cues are out of chronological order. |
Four cues, one error and three warnings. While the invalid cue was open the panel said "Resolve invalid timings before exporting.", and while a timing edit was still pending it said "Timing edits are not applied yet. Apply or discard them before exporting." In that pending state my export attempts produced no file at all.
The four repairs, and what each one did
The Timing step has two number fields and four switches, and the panel prints the order they are applied in: Sort by start time, Clamp timings before zero, Fix zero or negative durations, Move overlapping cues later. The app states its own rule in that order: "Overlap repair works chronologically and preserves durations; only Sort changes cue order. Overlap warnings alone do not block export."
I set Shift to -2,000 ms (negative values move earlier), set Repair duration to 1,000 ms, ticked all four switches and pressed Apply timing changes. The result read "4 cues", "No issues", a shift of 2,000 ms, and "4 repairs", with the status line "Timing changes applied to every loaded file. Originals are unchanged."
The repaired cue list:
| Cue | In | Out | Length | Line |
|---|---|---|---|---|
| 01 | 00:00:00,000 | 00:00:01,000 | 1.0 s | Earlier cue listed second |
| 02 | 00:00:01,500 | 00:00:03,500 | 2.0 s | Overlapping cue |
| 03 | 00:00:03,500 | 00:00:05,500 | 2.0 s | Later cue listed first |
| 04 | 00:00:06,000 | 00:00:07,000 | 1.0 s | Zero duration cue |
Row by row, the same four repairs are visible. The cue that started at 1.000 s moved 2 s earlier and would have started at -1.000, so it was clamped to zero, and its zero-length end was repaired to a full second. The cue that started at 5.000 s moved to 3.000, overlapped the previous cue ending at 3.500, and was moved later to 3.500 while keeping its 2.0 s length. The cue that started at 8.000 s moved to 6.000, still with a zero-length end, and was repaired to one second long. The cue that started at 3.500 s needed nothing beyond the shift itself.
The exports, read off disk
Three files came out, and I read all three back from disk rather than trusting the panel:
- Export SRT wrote
pasted-1-edited.srt, 214 bytes, with the repaired cues renumbered 1 to 4 in the new order. - Export all ZIP wrote
subtitles-edited.zip, 264 bytes, containing one 214-byte entry named1-pasted-1-edited.srt. - Switching the export format to WebVTT and pressing Export WebVTT wrote
pasted-1-edited.vtt, 222 bytes, starting with the WEBVTT header.
One difference between the two text formats showed up in the same run: the SRT export renumbered the cues 1 to 4 in the new order, while the WebVTT export kept the source cue identifiers (2, 4, 1, 3) in that same order. That is what the two files contained in this run; I did not check whether the app always does that.
Nothing leaves the tab
The panel's own line is "Nothing leaves this tab." I checked that on the wire rather than quoting it: with the network log on, the whole session issued 144 requests, none of them a POST or a PUT, and no request carried the subtitle text. The only calls beyond the page's own assets were our runtime and feature-flag endpoints, the sign-in widget and Cloudflare's beacon.
Limits
This is one browser, one signed-out session and one build on 6 November 2026. The file was my own four-cue fixture pasted as text, not a real-world subtitle file from a video. The optional reference-media control was not exercised. The original-download control under More file actions was not pressed. The app caps a batch at 20 files of 5 MB each, in UTF-8, and it does not transcribe audio.
I work on OnePassApps, and this is our own build, so the timings above are our own measurements rather than a third-party benchmark.

