Generalize the video-only reload spike into a per-type factory mirroring
resolve-track: reloadVideoTrack / reloadAudioTrack / reloadTextTrack, each
gating on its own selected*TrackId + track type so demuxed audio and video
reload independently. Inject fetchResolvableText via config (parity with
resolve-track, and testable). Update the live-playlist spike to reloadVideoTrack.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The HLS-tag-shaped name doesn't fit the format-neutral media model. startDate
parallels startTime (a segment carries both) and Track.startDate, while staying
protocol-neutral. Pure rename — no behavior change.
(Open question, deferred: whether a per-segment wall-clock field is needed at
all once Track.startDate is the anchor, or only re-emerges for discontinuities.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add anchorTrackToSequenceOrigin: re-bases a track's timeline to an estimated
stream start (the segment at startSequence, default 0) so startTime reads as
elapsed-since-stream-start and startDate becomes the wall clock at that origin.
The unseen earlier segments' duration is estimated from the observed segments'
average (more reliable than EXT-X-TARGETDURATION, a spec ceiling); present
segments keep their actual spacing. Rough and provisional — refined later from
the buffer; per-track.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add Track.startDate — the wall-clock time (epoch seconds) at a track's timeline
origin, derived in the parser as programDateTime − startTime and stable as the
window slides. Provisional from the manifest (refined later from the buffer).
Add alignTrackTimelines(tracks): a pure model transform that re-bases demuxed
tracks onto a common wall-clock origin by their startDate delta, so segments
with equal programDateTime get equal startTime — the cross-track A/V sync step.
Verified against the real demuxed Mux CMAF fixtures, where the 2s audio/video
skew resolves.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two decision docs for the live-HLS timeline work:
- mse-timestamp-offset — native-PTS default for live; timestampOffset reserved
for relocation (the manifest→buffer / encoded layer).
- live-timeline-anchoring — align demuxed tracks and recover turnover via PDT,
not sequence number (the manifest layer).
Resolve open questions [4] (sync anchor) and turnover startTime recovery in
live-presentation-modeling, pointing at the decisions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Surface absolute per-segment program-date-time (epoch seconds) on Segment,
interpolated forward via EXTINF and re-anchored on explicit tags. This is the
cross-track sync anchor for demuxed audio/video — where per-track relative
startTime disagrees, equal PDT identifies the same presentation instant — and
the exact recovery value on a full live-window turnover.
Surfacing only; PDT-anchored placement / the cross-track adjuster is a
follow-up. Adds synthetic unit tests plus sanitized real Mux live snapshots
(TS non-uniform slide; CMAF/LL-HLS demuxed A/V) as fixtures.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
POC spike for live HLS at the playlist layer only (no MSE/segments/DOM):
- parser surfaces target-duration / media-sequence / playlist-type / endlist
into a generic Ham.metadata bag (getMediaPlaylistMetadata accessor), with
stable media-sequence-derived segment ids
- parseMediaPlaylist(text, previous) takes a resolved-or-unresolved prior
track and carries the timeline forward across reloads (media-sequence
overlap + actual durations); first load anchors at 0; targetDuration used
only as the no-overlap fallback
- duration -> Infinity for unended live (finite once VOD/ENDLIST)
- streamType on Presentation, derived from PLAYLIST-TYPE alone
- reloadTrack behavior + createLivePlaylistSpikeEngine composition
WIP: startTime/timestampOffset basis and cross-track (A/V) sync are still
under research; PROGRAM-DATE-TIME capture and the cross-track alignment
strategy are not yet implemented.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Companion to presentation-modeling.md for streams that change over
time (live / DVR / event). Spine is a category decomposition that
keeps data separated by change-rate and consumer: content snapshot
(snapshot/merge segment identity via media-sequence + URL/byteRange),
streamType, completeness-as-duration, refetch policy as its own
category, the PROGRAM-DATE-TIME sync anchor, and the derived consumer
surface. Captures the debated decisions and open questions; scopes to
sliding-window live (LL-HLS / DVR / discontinuity / timestampOffset
deferred). Adds the reciprocal companion link in presentation-modeling.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>