Test files › Subtitles and captions › overlapping-cues.srt

Sample SRT file (overlapping cues)

SRT whose cues overlap in time and are not in chronological order, with one zero-length cue.

↓ Download overlapping-cues.srt
Filenameoverlapping-cues.srt
FormatSRT
Size252 bytes (252 bytes)
MIME typeapplication/x-subrip; charset=utf-8
SHA-256cf5259514f8ff313a3c625dab6d1932e5c8a7f7a3df74c58d89667ba68b41a86
What this file catchesRenderers that assume cues arrive sorted and never overlap. Overlapping cues are legal and must be shown together; a zero-length cue (identical start and end) is the one that causes divide-by-zero and infinite-loop bugs in timing code.

Handle it in code

Each snippet below was run against this exact file with Python 3.14.4 and Node 24.15.0 when this page was built, and the output shown is what it printed.

Python

SRT puts a comma before the milliseconds and WebVTT a full stop, and WebVTT files must start with WEBVTT. Players differ on the rest: overlapping cues are legal in WebVTT, but many SRT players show only one of them.

import re

TIME = r"(?:(\d+):)?(\d{2}):(\d{2})([.,])(\d{3})"
CUE = re.compile(TIME + r"\s+-->\s+" + TIME)

def ms(h, m, s, sep, frac):
    return ((int(h or 0) * 60 + int(m)) * 60 + int(s)) * 1000 + int(frac)

name = "overlapping-cues.srt"
vtt = name.lower().endswith(".vtt")
with open(name, encoding="utf-8-sig") as f:
    text = f.read()
problems, cues = [], []
if vtt and not text.startswith("WEBVTT"):
    problems.append("line 1: no WEBVTT signature")
for n, line in enumerate(text.splitlines(), 1):
    m = CUE.search(line)
    if not m:
        continue
    g = m.groups()
    right = "." if vtt else ","
    if g[3] != right or g[8] != right:
        problems.append(f"line {n}: {'WebVTT' if vtt else 'SRT'} needs {right!r} before the milliseconds")
    start, end = ms(*g[:5]), ms(*g[5:])
    if end < start:
        problems.append(f"line {n}: the cue ends before it starts")
    elif end == start:
        problems.append(f"line {n}: zero length, so it never shows")
    if cues:
        prev_start, prev_end = cues[-1]
        if start < prev_start:
            problems.append(f"line {n}: starts before the previous cue (out of order)")
        overlap = min(end, prev_end) - max(start, prev_start)
        if overlap > 0:
            problems.append(f"line {n}: overlaps the previous cue by {overlap} ms")
    cues.append((start, end))
print(f"{len(cues)} cues:", "valid" if not problems else f"{len(problems)} problem{'s' * (len(problems) != 1)}")
for p in problems:
    print("  " + p)

Run against this file, it prints: 3 cues: 3 problems line 6: starts before the previous cue (out of order) line 6: overlaps the previous cue by 2000 ms line 10: zero length, so it never shows

Related guides and tools

Character encodingsVerify its SHA-256

Download & verify

curl -fsSL -o "overlapping-cues.srt" "https://files.hexaqa.com/subtitle/overlapping-cues.srt"
curl -fsSL "https://files.hexaqa.com/subtitle/overlapping-cues.srt" | sha256sum # expect: cf5259514f8ff313a3c625dab6d1932e5c8a7f7a3df74c58d89667ba68b41a86

More subtitles and captions test files

comma-separator.vttmissing-signature.vttvalid.srtvalid.vtt

← All Subtitles and captions files