Spike/implementation working notes and pre-PR checklist. Internal AI-agent
context; drop or compact before merge if not wanted in the PR.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Design doc for the 3-coordinate model (startTime / startDate / startMediaTime)
and the timestampOffset relocation approach the reactor + steps implement.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Assets whose A/V encode starts at a non-zero native PTS (Mux instant clips,
Apple bipbop @10s) are relocated onto a 0-based presentation timeline via
`SourceBuffer.timestampOffset`, so buffer / model / `currentTime` / `seekable`
stay 0-based and the adapter is untouched.
- `establishStartMediaTime` reactor establishes each track's media-timeline
origin once per source (the DOM-free half), running an injected
`deriveStartMediaTime` seam over discovered container data.
- Default `deriveSharedMinStartMediaTime`: relocate every track by the `min`
across selected A/V origins — preserves real A/V skew and keeps every DTS >= 0.
Origins below NEAR_ZERO_ORIGIN_THRESHOLD (1s) are left native (ordinary
~0-PTS VOD isn't perturbed).
- `relocation-steps` message pipelines discover the origin (mdhd/tfdt head-peek)
and stamp `timestampOffset`; text cues rebase by X-TIMESTAMP-MAP − origin.
- Wired into both the default and audio-only HLS engines.
See internal/design/spf/presentation-timeline-model.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make a complete VOD reach native `ended` (and loop) reliably even when audio
and video tracks end a few ms apart:
1. `end-of-stream` reactor gains LAST_SEGMENT_REACHED_SLACK (0.5s) on the
"playhead reached the last segment" gate — a tiny final segment plus Chrome's
audio-clock freeze otherwise deadlocks endOfStream().
2. New `recover-end-stall` behavior: on `waiting`, if the MediaSource is
'ended' and the playhead is within endStallNudgeWindow (0.2s) of the
reachable buffered end (getMinBufferedEnd over the SourceBuffers), nudge
currentTime = duration to force native ended. Event-driven; inert for
live / clean-ending streams.
ADR: internal/decisions/end-of-stream-av-skew-recovery.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parse the WebVTT X-TIMESTAMP-MAP header (MPEGTS/LOCAL) and surface it as
text-segment metadata, so text-cue relocation can align cue times to the
relocated media timeline.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Minimal fMP4 box parser (media/mp4/box.ts) plus decode-time origin extraction
(timestamp-origin.ts) reading mdhd timescale + tfdt baseMediaDecodeTime, and a
head-peek primitive to read the leading bytes of a segment stream. Foundation
for relocating non-zero-PTS sources onto a 0-based presentation timeline.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>