Commit Graph
633 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
Wesley LuytenandGitHub 0460a48d93 fix(core): upgrade dash.js to 5.2.0 (#1724) 2026-06-23 12:59:33 -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 ff694a0dd8 fix(skin): add missing classnames to tailwind menus (#1712) 2026-06-19 14:23:24 +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
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
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
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
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
Renzo DelfinoandGitHub 48a984aecd fix(core): prevent mobile controls flash on first tap after auto-hide (#1556) 2026-06-10 14:39:39 -03:00
00b6f0be1d feat(packages): add settings menu (#1615)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 13:54:45 +10:00
Sam PottsandGitHub 62d0524b83 feat(core): lock fullscreen orientation (#1656) 2026-06-10 10:32:43 +10:00
Sam PottsandGitHub 3d2225e77e fix(packages): fix ejected skin slider setup (#1660) 2026-06-08 15:07:57 -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 24a78d253a refactor(core): airplay button (#1614) 2026-06-03 13:54:28 -07:00
Sam PottsandGitHub 7453d538a8 feat(skin): show scrubber preview timestamps (#1652) 2026-06-03 19:27:54 +10:00
Sam PottsandGitHub c5f75166fd feat(packages): update menu group labels (#1643) 2026-06-02 20:26:19 +10:00
Sam PottsandGitHub 2f5e23e100 fix(core): update trigger aria-expanded on close (#1644) 2026-06-02 17:07:20 +10:00
Sam PottsandGitHub e9a619e03a fix(core): focus selected radio menu items (#1645) 2026-06-02 16:40:11 +10:00
Santiago PuppoandGitHub efc7c23b7b fix(spf): add emptied listener to track-current-time behavior (#1634) 2026-06-01 16:54:58 -03:00