dash.js
Open Source Media Player
Seamless and reliable DASH streaming on any browser-based device
View onGitHub
5492
1731
443.3k
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 PascalThuet—21 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 PascalThuet—21 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 PascalThuet—21 hours ago






