feat: Configurable min-bandwidth-sample-duration-ms for hls.js EWMA estimator#1321
Open
luwes wants to merge 1 commit intomuxinc:mainfrom
Open
feat: Configurable min-bandwidth-sample-duration-ms for hls.js EWMA estimator#1321luwes wants to merge 1 commit intomuxinc:mainfrom
min-bandwidth-sample-duration-ms for hls.js EWMA estimator#1321luwes wants to merge 1 commit intomuxinc:mainfrom
Conversation
…igurable attribute Adds `min-bandwidth-sample-duration-ms` attribute and `minBandwidthSampleDurationMs` property on mux-video, mux-audio, and mux-player (plus the React and Astro wrappers) so callers can tune how short per-segment transfers are allowed to contribute to hls.js's EWMA bandwidth estimate. Previously SaneAbrController hard-coded the estimator's `minDelayMs_` floor to 5 ms. This PR replaces the constant with `createSaneAbrController(minDelayMs)` and restores the hls.js/Shaka historical default of 50 ms as the out-of-box value (preserving upstream behavior for everyone). Callers that want more aggressive short-transfer sampling can opt in with e.g. `min-bandwidth-sample-duration-ms="5"` or disable the clamp entirely with `"0"`. Also includes an interactive test page for observing and tuning the behavior at runtime. Made-with: Cursor
|
@luwes is attempting to deploy a commit to the Mux Team on Vercel. A member of the Team first needs to authorize it. |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related #1315
Test URL: https://elements-demo-vanilla-git-fork-luwes-feat-min-bandwi-4a56fa-mux.vercel.app/min-bandwidth-sample-duration-ms-test.html
Fixes an issue where very small segments at video startup are artificially lowering bandwidth calcs and engines choose lower qualities than is suitable.
Summary
Exposes the hls.js EWMA bandwidth estimator's
minDelayMs_floor as aconfigurable attribute/prop on mux-video, mux-audio, and
mux-player (plus the React and Astro wrappers), so callers can tune
how short per-segment transfers are allowed to contribute to the
bandwidth estimate.
min-bandwidth-sample-duration-msminBandwidthSampleDurationMs50(restores the hls.js / Shaka historical value —previously
SaneAbrControllerhard-coded it to5)Why
EwmaBandWidthEstimator#sample()clamps each fragment's downloadduration up to
minDelayMs_before computingbandwidth = 8000 × bytes / durationMs. The clamp defends against:otherwise poison the fast EWMA with multi-Gbps samples.
performance.now()resolution (historically ~1 ms, post-Spectreclamped to 100 µs – 2 ms) producing
duration = 0→Infinity.ACK timing dominate over actual network capacity.
hls.js inherited
50from Shaka in 2016. The assumptions behind thatnumber have weakened (4K/HDR ladders with small fragments on fast
connections routinely finish sub-50 ms), but some properties still
benefit from a conservative floor. Rather than pick a single magic
number globally, this PR exposes the knob so each integration can
tune it — with
0available as an opt-in for "disable the clampentirely."
What's plumbed
playback-core/sane-abr-controller.ts:MIN_DELAY_MS = 5→createSaneAbrController(minDelayMs)factory.DEFAULT_MIN_BANDWIDTH_SAMPLE_DURATION_MS = 50exported.SaneAbrControllerdefault export preserved (uses the default).playback-core/index.ts:setupHlspickscreateSaneAbrController(minBandwidthSampleDurationMs)when theprop is a number, otherwise the default class.
playback-core/types.ts:minBandwidthSampleDurationMs?: numberonMuxMediaPropTypes.mux-video/mux-audio: newBANDWIDTH…Attributesentry +matching getter/setter (parses to
number,undefinedwhen unset).mux-player: same getter/setter, forwards attribute to the innermux-videoviatemplate.ts, includes ingetProps(el)state.mux-video-react,mux-audio-react): added topropTypes.mux-player-react/mux-player-astrotypes gain theoptional prop. The existing camelCase → kebab-case conversion
handles attribute emission automatically.
Docs
packages/mux-player/REFERENCE.md— entries in both the attributeand property tables.
packages/mux-player-react/REFERENCE.mdpackages/mux-player-astro/REFERENCE.mdpackages/mux-video/README.mdTests
packages/playback-core/test/index.test.js— unit tests forcreateSaneAbrController(default, custom, reset re-pokesestimator) plus end-to-end assertion that
initialize({ … })propagates into
hls.abrController.bwEstimator.minDelayMs_.packages/mux-video/test/index.test.js— attribute/prop reflection0) + end-to-end propagation.packages/mux-audio/test/player.test.js— attribute/prop reflectionpackages/mux-player/test/player.test.js— attribute/propreflection + forwarding to the inner
<mux-video>.Interactive example page
New
examples/vanilla-ts-esm/public/min-bandwidth-sample-duration-ms-test.html:preload="none"to keep Play an explicit user action.localStorage, keyboard-resizable via ←/→).current rendition, segment count, count of clamped samples.
orange highlighting when the clamp kicked in.
CapLevelController(i.e. above
hls.autoLevelCapping)CapLevelControllerby settingcapRenditionToPlayerSize = false(which is only settable via theJS property, not the attribute — the test page sets it
synchronously after
appendChildso it's in place before themicrotask-deferred
load()).Backwards compatibility
minBandwidthSampleDurationMsdefaults to50— sameas upstream hls.js. Existing consumers see no behavior change.
SaneAbrControllerdefault export is preserved for anydirect importers (wired to the default).
Test plan
npm testpasses forplayback-core,mux-video,mux-audio,mux-player.renditions strip populates, dashboard updates, and the
minDelayMs_dashboard cell reflects the input.5and verify the configured floordashboard cell shows
5 msand some segments get flagged asclamped when the player is on a fast network.
strikethrough/hatched badges all disappear.
indicator updates live (cap recomputes on size change).
Made with Cursor
Note
Medium Risk
Touches playback/ABR initialization and reaches into hls.js internals (
bwEstimator.minDelayMs_), which can affect initial bitrate selection and buffering behavior across all MSE HLS playback paths.Overview
Adds a new
min-bandwidth-sample-duration-msattribute /minBandwidthSampleDurationMsprop acrossmux-video,mux-audio, andmux-player(plus React and Astro wrappers) to let callers configure the hls.js EWMA bandwidth estimator’s minimum sample-duration floor.In
playback-core, introducescreateSaneAbrController(minDelayMs)and wiressetupHls()to use it when the prop is provided (otherwise defaulting to the upstream 50ms behavior), with new unit/integration tests covering attribute reflection/forwarding and estimator configuration.Updates docs to describe the new knob and adds an interactive example page (
min-bandwidth-sample-duration-ms-test.html) to visualize how the floor impacts bandwidth estimates and rendition selection.Reviewed by Cursor Bugbot for commit 8927147. Bugbot is set up for automated code reviews on this repo. Configure here.