From cd0b9e17096ba12d1e21b454445de707f1dd698c Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Thu, 16 Jul 2026 22:44:51 -0600 Subject: [PATCH] fix(webvtt): don't shorten cues when splicing boundary duplicates --- tests/tracks/test_webvtt_merge.py | 11 +++++++++++ unshackle/core/utils/webvtt.py | 6 ++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/tracks/test_webvtt_merge.py b/tests/tracks/test_webvtt_merge.py index 07258e97..93ea61ce 100644 --- a/tests/tracks/test_webvtt_merge.py +++ b/tests/tracks/test_webvtt_merge.py @@ -79,6 +79,17 @@ def test_merge_splices_triple_duplicate_into_one(): assert "00:00:01.000 --> 00:00:04.000" in out +def test_merge_duplicate_ending_earlier_keeps_later_end(): + # A boundary duplicate that ends BEFORE the kept cue must not shorten it: the + # splice extends only. Here the kept cue runs to 00:00:05.000 and the duplicate + # is a brief 00:00:04.900 -> 00:00:04.950 re-emission of the same payload. + vtt = "WEBVTT\n\n00:00:01.000 --> 00:00:05.000\n[music]\n\nWEBVTT\n\n00:00:04.900 --> 00:00:04.950\n[music]\n" + out = merge_segmented_webvtt(vtt) + assert out.count("[music]") == 1 + assert "00:00:01.000 --> 00:00:05.000" in out, f"kept cue was truncated:\n{out}" + assert "00:00:04.950" not in out + + def test_merge_drops_cue_ids_and_notes_keeps_style(): vtt = ( "WEBVTT\n\n" diff --git a/unshackle/core/utils/webvtt.py b/unshackle/core/utils/webvtt.py index 11b3f67b..09ff17a6 100644 --- a/unshackle/core/utils/webvtt.py +++ b/unshackle/core/utils/webvtt.py @@ -62,8 +62,10 @@ def merge_segmented_webvtt(vtt_raw: str, segment_durations: Optional[list[int]] normalized = "\n".join(line.strip() for line in payload) if prev is not None and _timestamp_ms(start) - prev_end_ms <= 1 and normalized == prev[4]: - prev[1] = end # splice: extend the kept cue, drop the duplicate - prev_end_ms = _timestamp_ms(end) + end_ms = _timestamp_ms(end) + if end_ms > prev_end_ms: # splice: extend only, never shorten the kept cue + prev[1] = end + prev_end_ms = end_ms continue prev = [start, end, settings, "\n".join(payload), normalized]