Skip to content

feat(mux): mux-video / mux-player migration (phases 1–5, reference only)#1116

Draft
cjpillsbury wants to merge 14 commits intomainfrom
feat/mux-player-hls.js-migration
Draft

feat(mux): mux-video / mux-player migration (phases 1–5, reference only)#1116
cjpillsbury wants to merge 14 commits intomainfrom
feat/mux-player-hls.js-migration

Conversation

@cjpillsbury
Copy link
Copy Markdown
Collaborator

⚠️ Reference only — please do not merge

This is unintentional duplicate/parallel work. @luwes owns this effort — see his initial merged PR: #1036

Opening as a draft so the implementation approach, planning notes, and any useful code snippets are visible for reference. Please coordinate with @luwes before picking anything up from here.


What's in this branch

An independent port of @mux/mux-video / @mux/mux-player onto the VJS v10 delegate + mixin architecture, working from the @mux/playback-core and @mux/mux-player element repo as reference.

Completed phases (hls.js path)

Phase Description
1 MuxHlsMediaDelegate + MuxVideo element (hls.js config, cap-level controller, native MSE fallback)
2 Stream type detection (streamType, targetLiveWindow, liveEdgeOffset, liveEdgeStart) via LEVEL_LOADED
3 Error handling — MuxMediaError, MuxErrorCode, hls.js error mapping, 412 retry logic, pseudo-ended detection
4 DRM — Widevine + PlayReady + FairPlay via EME; engine recreated with getDRMConfig() when drm-token is set
5 Mux Data — mux.monitor() wired in MuxVideo connectedCallback; works on both hls.js and native paths

Not started

  • Phase 6: Convenience API (playback-id attribute, toMuxVideoURL(), prefer-playback, token attributes)
  • Phase 7: MuxPlayer UI

Known native path gaps (documented in .claude/plans/mux-player-migration.md)

  • Stream type detection (requires independent manifest fetch + parse)
  • Error handling (requires native error event listener + follow-up fetch for HTTP status)
  • DRM (requires eme-fairplay.ts + webkit-fairplay.ts)

Mux Data monitoring on the native path is implemented (calls mux.monitor() without hlsjs).

🤖 Generated with Claude Code

cjpillsbury and others added 14 commits March 24, 2026 11:25
…deo sandbox demos

Phase 1 of mux-player migration: introduces the core hls.js-based Mux media delegate with
a custom CapLevelController, HTML and React MuxVideo components, and sandbox demo templates.
Wire Hls.Events.LEVEL_LOADED in MuxHlsMediaDelegateBase to derive
streamType, targetLiveWindow, and liveEdgeOffset from each loaded
manifest. Dispatches streamtypechange and targetlivewindowchange
CustomEvents on the media element target when values change.

- stream-info.ts: getStreamInfoFromLevelDetails() maps LevelDetails
  to StreamInfo (on-demand / live / unknown, DVR via EVENT type,
  LL-HLS liveEdgeOffset via partTarget x 2)
- index.ts: adds streamType, targetLiveWindow, liveEdgeOffset,
  liveEdgeStart getters to MuxHlsMediaDelegateBase; resets on src
  change; uses Object.is() for NaN-safe targetLiveWindow comparison
- 13 tests covering VOD, sliding-window live, DVR, and LL-HLS cases

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Standalone test harness for smoke-testing mux-video stream type
detection. Shows streamType, targetLiveWindow, liveEdgeOffset, and
liveEdgeStart live as the manifest loads, with event logs for
streamtypechange and targetlivewindowchange. Preset VOD sources with
placeholder slots for live/DVR URLs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds structured error types, hls.js error mapping, 412 retry logic,
and pseudo-ended detection to MuxHlsMediaDelegateBase.

- errors.ts: MuxErrorCode, MuxErrorCategory, MuxMediaError class, and
  getErrorFromHlsErrorData() mapping hls.js ErrorData to structured
  errors. HTTP status codes mapped to MuxErrorCode without JWT
  inspection (deferred to Phase 6). Full DRM error mapping included.
- index.ts: wires Hls.Events.ERROR; 412 retries (6 max, 5s/60s);
  dispatches muxerror CustomEvent on fatal errors; pseudo-ended getter
  (paused within 34ms of duration); resets retry state on src change.
- 16 tests covering network status codes, DRM error variants, and
  generic fallthrough cases.
- sandbox harness logs muxerror events with muxCode label.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- add `drm.ts`: `getDRMConfig()` builds hls.js drmSystems config for
  Widevine (with HW_SECURE_ALL robustness), FairPlay, and PlayReady;
  `toPlaybackIdFromSrc()` extracts playback ID from stream.mux.com URLs
- wire DRM into `MuxHlsMediaDelegateBase`: `drmToken` getter/setter;
  engine is recreated with DRM config when `drmToken` is set before `src`
- add `drm-token` observed attribute to `MuxVideo` → flows into delegate
- add 14 tests covering URL extraction, DRM config, and key-system func

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- add `mux-embed` dependency to `packages/html`
- add `mux-data.ts`: `setupMuxData()` calls mux.monitor() with hls.js
  instance, automaticErrorTracking:false, and custom errorTranslator that
  suppresses hls.js internal string-coded events; returns destroyMonitor
  cleanup. Also exports `updateMuxHlsEngine`, `emitMuxError`, `emitMuxHeartbeat`
- wire mux monitoring into `MuxVideo` connectedCallback/disconnectedCallback;
  re-attaches HLS instance after DRM engine recreation on src change
- add `metadata` property on `MuxVideo` → live heartbeat via mux.emit('hb')
- add `env-key` to observedAttributes; exported `MuxMediaError` from core
- add `src/env.d.ts` to pick up mux-embed ambient type declarations
- add 13 tests covering monitor setup, error translation, cleanup, and emit helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mitations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l details

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
mux.monitor() works without an hlsjs instance — omit the option rather
than skipping setup entirely when engine is null.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 25, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
v10-sandbox Ready Ready Preview, Comment Mar 25, 2026 0:44am

Request Review

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 25, 2026

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 5315f67
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/69c33006dbd7ed0008ac525d
😎 Deploy Preview https://deploy-preview-1116--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant