dash.js

Open Source Media Player

Seamless and reliable DASH streaming on any browser-based device

View onGitHub
5492
1731

Sponsors

Trusted by the industry leaders

Latest updates from GitHub

MssFragmentMoofProcessor: crash when all DVR segments are removed in live MSS streams## Description In `MssFragmentMoofProcessor.js`, the DVR segment cleanup loop (lines 166-177) removes segments that fall before the `availabilityStartTime`. However, it does not check if the `segments` array becomes empty after each `splice()` call: ```javascript while (endTime < availabilityStartTime) { if (!playbackController.isPaused() && playbackController.getTime() < endTime) { break; } segments.splice(0, 1); segment = segments[0]; // undefined if array is now empty endTime = (segment.t + segment.d) / timescale; // TypeError! } ``` After the loop, `segments[0]` is also accessed without a length check (line 182) to compute the DVR range. ### Expected behavior The loop should check `segments.length > 0` both in the loop condition and after each splice. The DVR range update after the loop should also be guarded. ### Impact - **TypeError crash**: `Cannot read properties of undefined (reading 't')` - Occurs in live MSS streams when `timeShiftBufferDepth` is set and all segments in the timeline fall before the availability start time - This can happen during stream startup or after a long pause where all buffered segments become stale ### Steps to reproduce 1. Play a live MSS stream with a short `timeShiftBufferDepth` 2. Pause playback for a duration longer than `timeShiftBufferDepth` 3. Resume playback — the segment cleanup loop may remove all segments, causing a crash ### Version development branch (current HEAD)Opened by PascalThuet21 hours ago
ContentSteeringSelector: incorrect splice/indexOf arguments cause timer leak## Description In `ContentSteeringSelector.js`, the `_onAddBlackList()` function has a bug on line 111 where the arguments to `splice()` and `indexOf()` are incorrectly placed: ```javascript blacklistResetTimeout.splice(blacklistResetTimeout.indexOf(timer, 1)) ``` This line has **two bugs**: 1. **`indexOf(timer, 1)`** — the `1` is passed as the `fromIndex` parameter to `indexOf()`, meaning it starts searching from index 1. If the timer is at index 0, it will never be found and `indexOf` returns `-1`. 2. **`splice(index)` without a `deleteCount`** — calling `splice()` with only one argument removes **all elements** from that index to the end of the array, instead of just the one timer entry. ### Expected behavior ```javascript blacklistResetTimeout.splice(blacklistResetTimeout.indexOf(timer), 1) ``` The `1` should be the second argument to `splice()` (deleteCount), not to `indexOf()` (fromIndex). ### Impact - Timer references leak in the `blacklistResetTimeout` array - Valid timers may be incorrectly removed in bulk - Memory leak during long content steering sessions with frequent blacklist changes ### Steps to reproduce 1. Use content steering with a steering server that returns TTL-based blacklisting 2. Trigger multiple blacklist additions over time 3. Observe that the `blacklistResetTimeout` array grows unboundedly ### Version development branch (current HEAD)Opened by PascalThuet21 hours ago
perf: make GapController interval configurable and reduce hot-path allocations## Problem The GapController runs a periodic interval to detect and skip gaps in the media buffer. On resource-constrained devices (Smart TVs, set-top boxes), this creates unnecessary CPU wake-ups: - The interval is **hardcoded at 100ms** (10 calls/sec) with no way to tune it. For most use cases, a longer interval is sufficient to detect gaps without impacting user experience. - The check function allocates a temporary array via `Object.keys().some()` on every tick. ## Proposed Changes ### 1. Configurable gap check interval (main optimization) Replace the hardcoded `GAP_HANDLER_INTERVAL = 100` with a new `streaming.gaps.checkInterval` setting (default: **250ms**). This reduces timer wake-ups by 60%, which is meaningful on devices where the CPU is shared with the video decoder. The default can be tuned per device profile. ### 2. Reduce allocations in hot path - Replace `Object.keys(trackSwitchByMediaType).some()` with a `for..in` loop (avoids array allocation per tick) - Cache `settings.get().streaming.gaps` in `_jumpGap()` to avoid repeated property traversals These are minor improvements individually, but they follow the principle of avoiding unnecessary allocations in code that runs on a timer. ## Affected Files - `src/streaming/controllers/GapController.js` - `src/core/Settings.js` - `test/unit/test/streaming/streaming.controllers.GapController.js` ## Testing All 3242 existing unit tests pass. New tests cover the `checkInterval` default value and override via settings.Opened by PascalThuet21 hours ago

More news on

Contributors