Skip to content

stream.dash: fix t attr in SegmentTimeline - #7075

Merged
bastimeyer merged 1 commit into
streamlink:masterfrom
winklemad:fix/dash-timeline-gap
Sep 2, 2026
Merged

bastimeyer merged 1 commit into
streamlink:masterfrom
winklemad:fix/dash-timeline-gap

Conversation

@winklemad

Copy link
Copy Markdown
Contributor

SegmentTimeline.segments only honoured an <S> element's explicit @t when the running time was still 0:

t = 0
for tsegment in self.timeline_segments:
    if t == 0 and tsegment.t is not None:
        t = tsegment.t
    ...

So @t was applied on the first segment only. In a SegmentTimeline, a later <S t="..."> sets a new start time to signal a gap / discontinuity (per ISO/IEC 23009-1). That start time was ignored and the segment was placed at the accumulated time instead, producing wrong $Time$ values — and therefore requests for the wrong segments.

Example: <S t="0" d="4000" r="1"/> followed by <S t="10000" d="4000"/> should produce $Time$ = 0, 4000, 10000, but produced 0, 4000, 8000.

Fix

Apply @t whenever an <S> carries it, not only on the first segment. Contiguous timelines (no @t on later segments) are unaffected.

Test

Added test_segments_timeline_gap with a fixture MPD (dash/test_timeline_gap.mpd). On master the third segment is ?t=8000; with this change it is ?t=10000. The existing DASH segment tests stay green and ruff is clean.

AI-assisted contributions

I used an AI assistant (Claude Code) to help find this and draft the test. I verified it myself — reproduced the wrong $Time$ red→green through the real MPD parser, ran the DASH test suite, and confirmed ruff passes. I understand the change and take responsibility for it.

SegmentTimeline.segments only applied an <S> element's explicit @t when the
running time was still 0, i.e. on the first segment. A later <S> that carries
its own @t signals a gap/discontinuity in the timeline, but its start time was
ignored and the segment was placed at the accumulated time instead, producing
wrong $Time$ values (and therefore wrong segment requests). Apply @t whenever
it is present.

@bastimeyer bastimeyer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR.

It's a valid bug, even if discontinuities are not supported by Streamlink. The MPD must be followed correctly, or invalid segment requests will be made, causing actual errors.

The fix and unit test are looking fine...


ISO/IEC 23009-1:2022(E) Section 5.3.9.6.2:

Element or Attribute Name Use Description
SegmentTimeline specifies the Segment timeline information
S 0..N specifies Segment start time and duration for a contiguous sequence of segments or identical durations, referred to as series in the following.

Note: The S elements are ordered in sequence of increasing values of the attribute @t.
@t O this value of this attribute minus the value of the @presentationTimeOffset specifies the MPD start time, in @timescale units, of the first Segment in the series. The MPD start time is relative to the beginning of the Period.

The value of this attribute shall be equal to or greater than the sum of the previous S element earliest presentation time and the sum of the contiguous Segment durations.

If the value of the attribute is greater than what is expressed by the previous S element, it expresses discontinuities in the timeline.

If not present, then the value shall be assumed to be zero for the first S element and for the subsequent S elements, the value shall be assumed to be the sum of the previous S element's earliest presentation time and contiguous duration. [i.e. previous S@t + @d * (@r + 1)].

@bastimeyer bastimeyer changed the title stream.dash: honor an explicit @t on any SegmentTimeline segment stream.dash: fix t attr in SegmentTimeline Sep 2, 2026
@bastimeyer
bastimeyer merged commit 78531ba into streamlink:master Sep 2, 2026
33 of 34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants