feat(core): add media tracks and renditions support#1664
Conversation
Add audio/video track and rendition capability interfaces with a MediaTracksMixin, wire them through HlsJsMedia and the HlsMedia delegate, and fix media-attach disconnect ordering so features unwind before the host is destroyed.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| if (rendition.id && !levelIds.includes(rendition.id)) { | ||
| this.#currentVideoTrack.removeRendition(rendition); | ||
| } | ||
| } |
There was a problem hiding this comment.
LEVELS_UPDATED breaks rendition map
Medium Severity
#onLevelsUpdated decides which renditions to drop by looking up each incoming level in #levelIdMap, but that map is only populated during MANIFEST_PARSED. If LEVELS_UPDATED carries new level object references (typical when hls.js rebuilds its levels array), every lookup is undefined, so every rendition with an id is treated as stale and removed even though the levels still exist.
Reviewed by Cursor Bugbot for commit 0448d07. Configure here.
| } | ||
|
|
||
| addVideoTrack(media, event.track as VideoTrack); | ||
| }; |
There was a problem hiding this comment.
Native tracks linger after custom add
Medium Severity
When native videoTracks/audioTracks are mirrored and the app adds a real VideoTrack/AudioTrack via addVideoTrack/addAudioTrack, mirrored native entries stay in the custom list until a native addtrack event fires. The cleanup that removes native entries runs only inside the native addtrack listener, not when the custom track is added.
Reviewed by Cursor Bugbot for commit 0448d07. Configure here.
Compose MediaTracksMixin into DashMedia so DASH playback exposes track capabilities. Also guard remote.cancelWatchAvailability with optional chaining for engines lacking it.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 4 total unresolved issues (including 2 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 83dce08. Configure here.
|
|
||
| queueMicrotask(() => { | ||
| trackList.dispatchEvent(new TrackEvent('removetrack', { track })); | ||
| }); |
There was a problem hiding this comment.
Spurious removetrack after failed delete
Medium Severity
removeVideoTrack and removeAudioTrack always queue a removetrack event even when the track was not in the list. Native removetrack forwarding and duplicate removes can emit bogus events, so listeners may react to tracks that were never removed.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 83dce08. Configure here.
|
|
||
| nativeTracks.addEventListener('change', onChange); | ||
| nativeTracks.addEventListener('addtrack', onAddTrack); | ||
| nativeTracks.addEventListener('removetrack', onRemoveTrack); |
There was a problem hiding this comment.
Native track listeners never detached
Medium Severity
getVideoTracks / getAudioTracks register change, addtrack, and removetrack listeners on the native track list once, with no matching teardown on detach or destroy. After the host detaches, those handlers can keep firing and dispatch events on the synthetic lists.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 83dce08. Configure here.


Adds support for
audioTracksandvideoRenditionsto the HLS and Mux media.Add audio/video track and rendition capabilities to the media layer so engines can expose multivariant audio/video tracks and their underlying renditions through a consistent, framework-agnostic contract.
Changes
AudioTrackLike,VideoTrackLike,AudioRenditionLike,VideoRenditionLike, and their lists/capabilities) in the core media contractMediaTracksMixinproviding the track/rendition lists, composed intoHlsJsMediaHlsJsMediaMediaTracksMixinpopulates tracks/renditions, and theHlsMediadelegate forwardsvideoTracks/audioTracks/videoRenditions/audioRenditionsTesting
pnpm -F @videojs/core test— covered by new tests for the tracks mixin, HLS media tracks, and remote-playback teardown.Note
Medium Risk
Touches core playback selection (HLS level/audio switching) and new public media APIs, but changes are isolated to track lists with dedicated tests and no security-sensitive paths.
Overview
Adds a framework-agnostic audio/video track and rendition layer so players can expose multivariant choices and quality levels through a single contract, not only through engine-specific APIs.
The PR introduces track/rendition types and list implementations (with
addtrack/changestyle events),MediaTracksMixinto attachaudioTracks,videoTracks,audioRenditions, andvideoRenditionsto media hosts (replacing or bridging native track getters where needed), and extendstypes.tswith the corresponding capability interfaces.HLS (hls.js) is wired via
HlsJsMediaMediaTracksMixin: manifest levels become video renditions on a selected video track, alternate audio becomesaudioTracks, and user changes on those lists driveengine.nextLevelandengine.audioTrack.HlsMediaforwards the four properties only when the MSE delegate isHlsJsMedia.DashMediacomposesMediaTracksMixinfor the same host shape (engine-specific population is not in this diff).Smaller fixes:
MediaAttachMixindetaches the store beforesuper.disconnectedCallback()so remote-playback cleanup still sees a live element;remote-playbackuses optionalcancelWatchAvailabilityon abort.Reviewed by Cursor Bugbot for commit 83dce08. Bugbot is set up for automated code reviews on this repo. Configure here.