Commit Graph
1066 Commits
Author SHA1 Message Date
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 a2edaba81d docs(spf): record live timeline anchoring + MSE timestampOffset decisions
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>
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
Christian PillsburyandClaude Opus 4.8 820f6fe45c docs(spf): add live-presentation-modeling design doc
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>
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
a5a7953603 chore(site): upgrade to Astro 7 and consolidate on Vite 8 (#1721)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-23 14:23:21 -07:00
Wesley LuytenandGitHub 0460a48d93 fix(core): upgrade dash.js to 5.2.0 (#1724) 2026-06-23 12:59:33 -07:00
b8b1709db5 fix(site): pre-bundle react-dom so dev islands hydrate (#1711)
Co-authored-by: Claude <noreply@anthropic.com>
2026-06-22 09:43:49 -07: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
Sam PottsandGitHub 1512729365 fix(ci): run bundle size on stacked prs (#1713) 2026-06-19 14:48:58 +10:00
Sam PottsandGitHub ff694a0dd8 fix(skin): add missing classnames to tailwind menus (#1712) 2026-06-19 14:23:24 +10:00
17d6ebfc30 fix(ci): report lazy bundle chunks separately (#1710)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-06-19 13:42:08 +10:00
edfec1c93e revert(core): unmerge i18n stack base (#1707)
Co-authored-by: Wesley Luyten <me@wesleyluyten.com>
2026-06-18 15:20:35 -07:00
f0f9eed544 refactor(core)!: move media capability predicates to core layer (#1705)
Co-authored-by: Rahim <rahim.alwer@gmail.com>
2026-06-18 15:00:26 -07:00
accf4bfa34 fix(packages): escape HTML special chars in serializeAttributes to prevent XSS (#1670)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Wesley Luyten <me@wesleyluyten.com>
2026-06-18 12:23:19 -07:00
9170a5879e feat(core): add built-in locale packs and lazy loadLocale (#1590)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-18 12:16:47 -07:00
768bf09da0 feat(core): add i18n foundation with English locale and UI wiring (#1589)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Wesley Luyten <me@wesleyluyten.com>
2026-06-18 11:55:38 -07:00
fa768da757 docs(site): add Google Cast documentation (#1681)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 11:42:19 -07:00
9bcdf5ffc2 fix(site): update use-media reference for mediahost architecture (#1702)
Co-authored-by: Darius Cepulis <dcepulis@mux.com>
2026-06-18 11:14:45 -07:00
Renzo DelfinoandGitHub 964d9ca1d7 docs(site): document self-hosted and offline player builds (#1680) 2026-06-18 14:48:22 -03:00
Manuel CallerizaandGitHub 67e1bc17c6 docs(react): clarify usePlayer typed vs untyped store access (#1663) 2026-06-18 14:46:01 -03:00
Ronald UrbinaandGitHub 0b1491c30e docs(site): add "No Skin" option to installation skin picker (#1525) 2026-06-18 12:07:23 -03:00
Ronald UrbinaandGitHub 07428519a5 feat(packages): add poster placeholder blur-up pattern (#1632) 2026-06-18 12:05:41 -03:00
Wesley LuytenandGitHub b32b80e55b refactor(core): rework media config as a plain getter/setter (#1697) 2026-06-17 17:58:52 -07:00
Wesley LuytenandGitHub 1b31f3e8d7 feat(core): add vimeo media host and html/react components (#1667) 2026-06-18 09:36:31 +10:00
Sam PottsandGitHub 035b509c7a feat(packages): compound tooltips with label and shortcut parts (#1494) 2026-06-18 08:12:16 +10:00
Sam PottsandGitHub 9275f93504 feat(packages): add resolved rendition to auto label (#1698) 2026-06-18 07:42:00 +10:00
eae0191eed chore(ci): drop edited trigger from issue triage (#1700)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:28:38 -07:00
Sam PottsandGitHub 16ab90987a feat(packages): add quality menu UI (#1694) 2026-06-18 07:20:59 +10:00
Sam PottsandGitHub 74da6821d7 feat(core): add quality selection state (#1693) 2026-06-18 07:20:13 +10: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
Ronald UrbinaandGitHub 47aca0f798 fix(core): remove 1-9 digit key seek from slider keyboard handler (#1690) 2026-06-16 10:50:16 -03:00
Wesley LuytenandGitHub 67b39fe4bd feat(core): add media tracks and renditions support (#1664) 2026-06-15 07:39:55 +10:00
Wesley LuytenandGitHub 0ffe1a9197 feat(media)!: add Google Cast by default to HLS, DASH media (#1661) 2026-06-12 17:34:14 -07:00
Renzo DelfinoandGitHub 1145f09e52 feat(site): list required css imports per skin in preset reference (#1521) 2026-06-12 14:57:42 -03:00
Sam PottsandGitHub 4a81e048a1 fix(test): stabilize e2e tests (#1678) 2026-06-12 07:13:07 +10: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
Sam PottsandGitHub b9e0a75c1b fix(react): address stale media reference (#1677) 2026-06-11 09:37:28 -07:00
Ronald UrbinaandGitHub e10455aed7 fix(docs): replace <Controls /> with <Controls.Root> in code samples (#1492) 2026-06-11 11:22:39 -03:00
Sam PottsandGitHub 6b0d3b6b2f fix(test): update e2e menu selectors (#1674) 2026-06-11 12:29:59 +10:00