diff --git a/karma.conf.js b/karma.conf.js index 13d13bd1..0eab1731 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -34,7 +34,7 @@ module.exports = function (config) { client: { mocha: { reporter: 'html', - timeout: 10000 + timeout: 20000 } } }; diff --git a/src/dash-adapter.js b/src/dash-adapter.js index ad9ed0fe..3250a61b 100644 --- a/src/dash-adapter.js +++ b/src/dash-adapter.js @@ -216,6 +216,9 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @private */ _thumbnailController: ?DashThumbnailController; + _isStartOver: boolean = true; + _seekRangeStart: number = 0; + _startOverTimeout: TimeoutID; /** * Factory method to create media source adapter. @@ -719,6 +722,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { this._eventManager.listen(this._shaka, ShakaEvent.DRM_SESSION_UPDATE, this._adapterEventsBindings.drmsessionupdate); this._eventManager.listen(this._videoElement, EventType.WAITING, this._adapterEventsBindings.waiting); this._eventManager.listen(this._videoElement, EventType.PLAYING, this._adapterEventsBindings.playing); + this._eventManager.listen(this._videoElement, EventType.LOADED_DATA, () => this._onLoadedData()); this._eventManager.listenOnce(this._videoElement, EventType.PLAYING, () => { this._eventManager.listen(this._shaka, ShakaEvent.BUFFERING, this._adapterEventsBindings.buffering); }); @@ -744,6 +748,17 @@ export default class DashAdapter extends BaseMediaSourceAdapter { }); } + _onLoadedData(): void { + const segmentDuration = this.getSegmentDuration(); + this._seekRangeStart = this._shaka.seekRange().start; + this._startOverTimeout = setTimeout(() => { + if (this._shaka.seekRange().start - this._seekRangeStart >= segmentDuration) { + // in start over the seekRange().start should be permanent + this._isStartOver = false; + } + }, (segmentDuration + 1) * 1000); + } + /** * Custom parser to retrieve image adaptation sets. * @param {ArrayBuffer} manifestBuffer - The array buffer manifest from the response. @@ -846,6 +861,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { this._thumbnailController = null; this._clearStallInterval(); this._clearVideoUpdateTimer(); + clearTimeout(this._startOverTimeout); if (this._eventManager) { this._eventManager.removeAll(); } @@ -1300,7 +1316,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { */ getStartTimeOfDvrWindow(): number { if (this.isLive() && this._shaka) { - return this._shaka.seekRange().start + this._shaka.getConfiguration().streaming.safeSeekOffset; + return (this._isStartOver ? this._seekRangeStart : this._shaka.seekRange().start) + this._shaka.getConfiguration().streaming.safeSeekOffset; } return 0; } diff --git a/test/src/dash-adapter.spec.js b/test/src/dash-adapter.spec.js index c0c13819..fb0e2ece 100644 --- a/test/src/dash-adapter.spec.js +++ b/test/src/dash-adapter.spec.js @@ -1342,9 +1342,8 @@ describe('DashAdapter: getStartTimeOfDvrWindow', () => { it('should return the start time of Dvr window for live', done => { dashInstance = DashAdapter.createAdapter(video, liveSource, config); - dashInstance - .load() - .then(() => { + video.addEventListener(EventType.LOADED_DATA, () => { + setTimeout(() => { try { Math.floor(dashInstance.getStartTimeOfDvrWindow()).should.equal( Math.floor(dashInstance._shaka.seekRange().start + dashInstance._shaka.getConfiguration().streaming.safeSeekOffset) @@ -1353,10 +1352,9 @@ describe('DashAdapter: getStartTimeOfDvrWindow', () => { } catch (e) { done(e); } - }) - .catch(e => { - done(e); - }); + }, (dashInstance.getSegmentDuration() + 2) * 1000); + }); + dashInstance.load(); }); });