Skip to content

Commit

Permalink
fix: seeking live streams when missing mediaSource.setLiveSeekableRan…
Browse files Browse the repository at this point in the history
…ge (#26)

* fix: set media source duration when setLiveSeekableRange is not available

* feat: added config.streaming.buffer.enableLiveSeekableRangeFix

* fix: set enableSetLiveSeekableRangeFix to true by default

* fix: remove debug code

* refactor: guards

* chore: update setting name

* chore: remove debug code

* 4.3.5
  • Loading branch information
grabofus authored Jun 30, 2022
1 parent e5e7882 commit dbfdec0
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 12 deletions.
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ declare namespace dashjs {
longFormContentDurationThreshold?: number,
stallThreshold?: number,
useAppendWindow?: boolean,
setStallState?: boolean
setStallState?: boolean,
enableLiveSeekableRangeFix?: boolean
},
gaps?: {
jumpGaps?: boolean,
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dashjs",
"version": "4.3.4",
"version": "4.3.5",
"description": "A reference client implementation for the playback of MPEG DASH via Javascript and compliant browsers.",
"author": "Dash Industry Forum",
"license": "BSD-3-Clause",
Expand Down
8 changes: 6 additions & 2 deletions src/core/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* longFormContentDurationThreshold: 600,
* stallThreshold: 0.5,
* useAppendWindow: true,
* setStallState: false
* setStallState: false,
* enableLiveSeekableRangeFix: true
* },
* gaps: {
* jumpGaps: true,
Expand Down Expand Up @@ -301,6 +302,8 @@ import {HTTPRequest} from '../streaming/vo/metrics/HTTPRequest';
* Specifies if the appendWindow attributes of the MSE SourceBuffers should be set according to content duration from manifest.
* @property {boolean} [setStallState=false]
* Specifies if we fire manual waiting events once the stall threshold is reached
* @property {boolean} [enableLiveSeekableRangeFix=true]
* Sets `mediaSource.duration` when live seekable range changes if `mediaSource.setLiveSeekableRange` is unavailable.
*/

/**
Expand Down Expand Up @@ -801,7 +804,8 @@ function Settings() {
longFormContentDurationThreshold: 600,
stallThreshold: 0.3,
useAppendWindow: true,
setStallState: true
setStallState: true,
enableLiveSeekableRangeFix: true
},
gaps: {
jumpGaps: true,
Expand Down
38 changes: 33 additions & 5 deletions src/streaming/controllers/MediaSourceController.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,55 @@ function MediaSourceController() {
videoModel.setSource(null);
}

function setDuration(value) {
function setDuration(value, log = true) {
if (!mediaSource || mediaSource.readyState !== 'open') return;
if (value === null && isNaN(value)) return;
if (mediaSource.duration === value) return;

if (!isBufferUpdating(mediaSource)) {
logger.info('Set MediaSource duration:' + value);
if (log) {
logger.info('Set MediaSource duration:' + value);
}
mediaSource.duration = value;
} else {
setTimeout(setDuration.bind(null, value), 50);
}
}

function setSeekable(start, end) {
if (mediaSource && typeof mediaSource.setLiveSeekableRange === 'function' && typeof mediaSource.clearLiveSeekableRange === 'function' &&
mediaSource.readyState === 'open' && start >= 0 && start < end) {
function setSeekable(start, end, enableLiveSeekableRangeFix) {
if (!mediaSource || mediaSource.readyState !== 'open') return;
if (start < 0 || end <= start) return;

if (typeof mediaSource.setLiveSeekableRange === 'function' && typeof mediaSource.clearLiveSeekableRange === 'function') {
mediaSource.clearLiveSeekableRange();
mediaSource.setLiveSeekableRange(start, end);
} else if (enableLiveSeekableRangeFix) {
try {
const bufferedRangeEnd = getBufferedRangeEnd(mediaSource);
const targetMediaSourceDuration = Math.max(end, bufferedRangeEnd);
if (!isFinite(mediaSource.duration) || mediaSource.duration < targetMediaSourceDuration) {
setDuration(targetMediaSourceDuration, false);
}
} catch (e) {
logger.error(`Failed to set MediaSource duration! ` + e.toString());
}
}
}

function getBufferedRangeEnd(source) {
let max = 0;
const buffers = source.sourceBuffers;

for (let i = 0; i < buffers.length; i++) {
if (buffers[i].buffered.length > 0) {
const end = buffers[i].buffered.end(buffers[i].buffered.length - 1);
max = Math.max(end, max);
}
}

return max;
}

function signalEndOfStream(source) {
if (!source || source.readyState !== 'open') {
return;
Expand Down
8 changes: 6 additions & 2 deletions src/streaming/controllers/StreamController.js
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ function StreamController() {

_setMediaDuration();
const dvrInfo = dashMetrics.getCurrentDVRInfo();
mediaSourceController.setSeekable(dvrInfo.range.start, dvrInfo.range.end);
mediaSourceController.setSeekable(dvrInfo.range.start, dvrInfo.range.end, _enableLiveSeekableRangeFix());
_activateStream(seekTime, keepBuffers);
}

Expand Down Expand Up @@ -611,6 +611,10 @@ function StreamController() {
}
}

function _enableLiveSeekableRangeFix() {
return settings.get().streaming.buffer.enableLiveSeekableRangeFix;
}

/**
* Initiate the preloading of the next stream
* @param {object} nextStream
Expand Down Expand Up @@ -1487,7 +1491,7 @@ function StreamController() {
//Should we normalize and union the two?
const targetMediaType = hasAudioTrack() ? Constants.AUDIO : Constants.VIDEO;
if (e.mediaType === targetMediaType) {
mediaSourceController.setSeekable(e.value.range.start, e.value.range.end);
mediaSourceController.setSeekable(e.value.range.start, e.value.range.end, _enableLiveSeekableRangeFix());
}
}
}
Expand Down

0 comments on commit dbfdec0

Please sign in to comment.