Commit Graph
81 Commits
Author SHA1 Message Date
Christian PillsburyandClaude Opus 4.8 6780a44ccb fix(spf): make seekToLiveEdge model-driven (declare seekable range + seek)
The buffered-driven version couldn't fire at cold-start: live segments append
at native PTS, so currentTime=0 is outside the buffered window, but the loader
only fetches segments overlapping [currentTime, currentTime+bufferDuration], so
nothing loads until the playhead is in the window — a deadlock (no buffer → no
seek → no load).

Now derive the window from the selected video track's anchored timeline:
setLiveSeekableRange(windowStart, windowEnd) (re-declared as the window slides)
and seek currentTime to the window start once. Verified end-to-end against a
live Mux CMAF/LL-HLS stream: automatic playback, native-PTS buffered range
matches the seq-0-anchored model (Mux tfdt is stream-relative).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:59:21 -07:00
Christian PillsburyandClaude Opus 4.8 4a58e85015 feat(spf): export ./live-hls + sandbox live-engine harness
Add the ./live-hls subpath export (build entry + package export) and a
LiveHlsEngineSignals type. Add a bare sandbox template (live-hls-engine) that
wires createLiveHlsEngine to a raw <video> — no player/skin — and logs playback
state, for end-to-end live-playback verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:59:21 -07:00
Christian PillsburyandClaude Opus 4.8 bbaeb52ed8 feat(spf): seekToLiveEdge behavior + wire into live engine
Live segments append at native PTS, so the buffered range sits at a large
timestamp while currentTime starts at 0 — no data at 0, readyState never
advances, playback can't start. seekToLiveEdge watches for the buffered range
and seeks the playhead into it (window start) once present. Listens to events
that fire without data at currentTime (loadedmetadata/durationchange/progress);
once per source. Composed into createLiveHlsEngine.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:58:46 -07:00
Christian PillsburyandClaude Opus 4.8 bd6ea19f8d feat(spf): live HLS engine composition
Add createLiveHlsEngine: reuses the VoD engine's MSE/segment/ABR behaviors,
swaps one-shot resolve* for the per-type live reload loop, defaults
resolveDuration to Infinity, and adds anchorLiveTracks — a behavior that applies
the per-track stream-origin anchor to the selected tracks so segment.startTime ≈
native PTS (what the segment loader matches currentTime against). Cross-track
alignment is intentionally not composed yet (it would fight the per-track anchor
in a re-firing effect); residual skew is absorbed by native-PTS A/V sync.

Demuxed audio+video; text/discontinuity out of scope. Not yet wired to a DOM
element — engine composition + anchor behavior only, both typecheck/build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 09:58:46 -07:00
Christian PillsburyandClaude Opus 4.8 df4ec77c18 feat(spf): per-type live media-playlist reload
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>
2026-06-25 09:58:45 -07:00
Christian PillsburyandClaude Opus 4.8 0cec3132a9 refactor(spf): rename Segment.programDateTime → Segment.startDate
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>
2026-06-25 09:58:45 -07:00
Christian PillsburyandClaude Opus 4.8 13996a654d feat(spf): estimate stream-origin startDate from media sequence
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>
2026-06-25 09:58:45 -07:00
Christian PillsburyandClaude Opus 4.8 bf8e87d237 feat(spf): cross-track PDT timeline alignment
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>
2026-06-25 09:58:45 -07:00
Christian PillsburyandClaude Opus 4.8 e24b2bf7ca feat(spf): capture EXT-X-PROGRAM-DATE-TIME in the HLS media-playlist parser
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>
2026-06-25 09:58:44 -07:00
Christian PillsburyandClaude Opus 4.8 c0c9eb348d feat(spf): live media-playlist reload spike + parser timeline (WIP)
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>
2026-06-25 09:58:44 -07:00
Santiago PuppoandGitHub a74b8c0993 refactor: Rename SPF background-looping-video into background-video (#1731) 2026-06-24 11:09:20 -03:00
23538e3649 feat(spf): text tracks switching (#1687)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 07:54:51 -07:00
Darius CepulisandGitHub d799be1063 feat(site): API reference pages for media elements (#1342) 2026-06-19 09:44:54 -07:00
bce79ec424 feat(spf): capability probing (#1676)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 11:22:49 -07:00
b89f1e944c feat(spf): multi cdn failover (#1671)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 08:20:43 -07:00
Santiago PuppoandGitHub 33873bc4ae feat(spf): Add maxResolution to SPF Background Video (#1654) 2026-06-17 11:36:02 -03:00
00aa6247b8 feat(spf): multi-cdn support (#1668)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 10:09:16 -07:00
d9f9efde88 fix(spf): refactor track switching to rules (#1658)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 14:48:34 -07:00
057f32573e feat(spf): multi-track audio + skills building features and behaviors (#1605)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 09:53:13 -07:00
Santiago PuppoandGitHub efc7c23b7b fix(spf): add emptied listener to track-current-time behavior (#1634) 2026-06-01 16:54:58 -03:00
Santiago PuppoandGitHub 3741e8de12 feat(spf): background looping video (phase 1) (#1602) 2026-06-01 16:13:26 -03:00
1a3cb45b29 feat(spf): basic audio only use case + use-case-composition doc-type + implementation skills (#1584)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 12:48:40 -07:00
Sam PottsandGitHub 760870fdf2 fix(core): disable toggle captions when there are no captions (#1598) 2026-05-26 09:49:50 +10:00
c9d6ccecdd docs(spf): seed feature registry, clusters reference, and document-feature skill (#1581)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 12:07:33 -07:00
1a3911151a chore(build): quiet tsdown size reports in local dev (#1569)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 11:38:26 +10:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
5f1c2370fa chore: release main (#1477)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-19 12:48:40 -07:00
c112b6248b fix(spf): conventions, per-type specialization, config threading (#1537)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 11:38:47 -07:00
8fa63c6567 feat(spf) discrete signals and behavior objects (#1508)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:32:44 -07:00
0cfd3bb395 feat(spf): HLS engine composition walkthrough + doc-driven cleanups (#1512)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 12:07:26 -07:00
Christian PillsburyandGitHub 69852ddeb0 docs/spf fundamental concepts (#1396)
Feedback from @decepulis treated as a fast follow/incremental improvement effort for expediency.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 11:16:56 -07:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
cce48c01fa chore: release main (#1375)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-27 13:47:20 -07:00
rahimandGitHub 84c9e540bd chore(root): migrate typecheck to @typescript/native-preview (tsgo) (#1400) 2026-04-23 11:11:50 +10:00
2f7212028c refactor(react): replace prototype-walking and inferred class props (#1376)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 09:20:46 -07:00
Wesley LuytenandGitHub 000c54e16a chore: release main (#1353) 2026-04-18 01:18:23 -07:00
Wesley LuytenandGitHub 8530316987 revert(packages): add server-only bundles (#1349) (#1354) 2026-04-17 11:44:53 -07:00
rahimandGitHub 3331fdaf25 fix(packages): add server-only bundles (#1349) 2026-04-16 00:59:14 -07:00
Wesley LuytenandGitHub 521774a95b chore: release main (#1341) 2026-04-14 17:19:40 -05:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
77faf060d4 chore: release main (#1339)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-14 17:11:09 -05:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c2cb16bd8b chore: release main (#1336)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-14 16:54:01 -05:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
da598b285a chore: release main (#1313)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-14 15:58:18 -05:00
Wesley LuytenandGitHub 8f1653efcd refactor(packages)!: replace DelegateMixin & ProxyMixin with MediaHost base classes (#1292) 2026-04-14 00:18:11 -05:00
Wesley LuytenandGitHub d67a3699e4 chore: release main (#1308) 2026-04-10 22:09:56 -07:00
Wesley LuytenandGitHub 12877c34fc chore: release main (#1232) 2026-04-10 15:18:11 -07:00
1346d869ae feat(spf): architecture reactors (#1218)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 13:38:24 -07:00
rahimandGitHub 071325de4d fix(utils): stable sort comparator and orphaned JSDoc (#1286) 2026-04-08 17:39:28 +10:00
rahimandGitHub b874dad306 fix(packages): workspace drift (#1270) 2026-04-07 21:15:23 -07:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
d75cd82ef8 chore: release main (#1212)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-04-03 17:56:01 -05:00
Wesley LuytenandGitHub dcb4587dba chore: release main (#1193) 2026-04-03 00:19:11 -07:00
Wesley LuytenGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
63a82c0f92 chore: release main (#1170)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-31 20:37:58 -05:00
Wesley LuytenandGitHub d7d6f70797 chore: release main (#1115) 2026-03-31 17:11:33 -07:00