From 4246079f175290a0f67905776a663ae3e87a4fcc Mon Sep 17 00:00:00 2001 From: Dan Ziv Date: Thu, 31 Aug 2017 12:18:39 +0300 Subject: [PATCH] fix(FEC-6968): loadstart issue (#26) --- src/dash-adapter.js | 85 +++++++++++++++++++++++------------ test/src/dash-adapter.spec.js | 49 +++++++------------- 2 files changed, 72 insertions(+), 62 deletions(-) diff --git a/src/dash-adapter.js b/src/dash-adapter.js index 37f15835..7558278c 100644 --- a/src/dash-adapter.js +++ b/src/dash-adapter.js @@ -131,7 +131,16 @@ export default class DashAdapter extends BaseMediaSourceAdapter { constructor(videoElement: HTMLVideoElement, source: Object, config: Object = {}) { DashAdapter._logger.debug('Creating adapter. Shaka version: ' + shaka.Player.version); super(videoElement, source, config); - this._shaka = new shaka.Player(videoElement); + + } + + /** + * Runs the initialization actions of the dash adapter. + * @private + * @returns {void} + */ + _init(): void { + this._shaka = new shaka.Player(this._videoElement); this._maybeSetDrmConfig(); this._shaka.configure(this._config); this._shaka.setTextTrackVisibility(true); @@ -179,6 +188,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { */ load(startTime: ?number): Promise { if (!this._loadPromise) { + this._init(); this._loadPromise = new Promise((resolve, reject) => { if (this._sourceObj && this._sourceObj.url) { this._trigger(BaseMediaSourceAdapter.CustomEvents.ABR_MODE_CHANGED, {mode: this.isAdaptiveBitrateEnabled() ? 'auto' : 'manual'}); @@ -206,8 +216,10 @@ export default class DashAdapter extends BaseMediaSourceAdapter { super.destroy(); this._loadPromise = null; this._sourceObj = null; - this._removeBindings(); - this._shaka.destroy(); + if (this._shaka) { + this._removeBindings(); + this._shaka.destroy(); + } if (DashAdapter._drmProtocol) { DashAdapter._drmProtocol.destroy(); DashAdapter._drmProtocol = null; @@ -255,10 +267,13 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @private */ _getParsedTracks(): Array { - let videoTracks = this._getParsedVideoTracks(); - let audioTracks = this._getParsedAudioTracks(); - let textTracks = this._getParsedTextTracks(); - return videoTracks.concat(audioTracks).concat(textTracks); + if (this._shaka) { + let videoTracks = this._getParsedVideoTracks(); + let audioTracks = this._getParsedAudioTracks(); + let textTracks = this._getParsedTextTracks(); + return videoTracks.concat(audioTracks).concat(textTracks); + } + return []; } /** @@ -343,17 +358,19 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ selectVideoTrack(videoTrack: VideoTrack): void { - let videoTracks = this._getVideoTracks(); - if ((videoTrack instanceof VideoTrack) && videoTracks) { - let selectedVideoTrack = videoTracks[videoTrack.index]; - if (selectedVideoTrack) { - if (this.isAdaptiveBitrateEnabled()) { - this._shaka.configure({abr: {enabled: false}}); - this._trigger(BaseMediaSourceAdapter.CustomEvents.ABR_MODE_CHANGED, {mode: 'manual'}); - } - if (!selectedVideoTrack.active) { - this._shaka.selectVariantTrack(videoTracks[videoTrack.index], true); - this._onTrackChanged(videoTrack); + if (this._shaka) { + let videoTracks = this._getVideoTracks(); + if ((videoTrack instanceof VideoTrack) && videoTracks) { + let selectedVideoTrack = videoTracks[videoTrack.index]; + if (selectedVideoTrack) { + if (this.isAdaptiveBitrateEnabled()) { + this._shaka.configure({abr: {enabled: false}}); + this._trigger(BaseMediaSourceAdapter.CustomEvents.ABR_MODE_CHANGED, {mode: 'manual'}); + } + if (!selectedVideoTrack.active) { + this._shaka.selectVariantTrack(videoTracks[videoTrack.index], true); + this._onTrackChanged(videoTrack); + } } } } @@ -367,7 +384,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ selectAudioTrack(audioTrack: AudioTrack): void { - if ((audioTrack instanceof AudioTrack) && !audioTrack.active) { + if (this._shaka && (audioTrack instanceof AudioTrack) && !audioTrack.active) { this._shaka.selectAudioLanguage(audioTrack.language); this._onTrackChanged(audioTrack); } @@ -381,7 +398,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ selectTextTrack(textTrack: TextTrack): void { - if ((textTrack instanceof TextTrack) && !textTrack.active && (textTrack.kind === 'subtitles' || textTrack.kind === 'captions')) { + if (this._shaka && (textTrack instanceof TextTrack) && !textTrack.active && (textTrack.kind === 'subtitles' || textTrack.kind === 'captions')) { this._shaka.selectTextLanguage(textTrack.language); this._shaka.setTextTrackVisibility(true); this._onTrackChanged(textTrack); @@ -395,7 +412,9 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ hideTextTrack(): void { - this._shaka.setTextTrackVisibility(false); + if (this._shaka) { + this._shaka.setTextTrackVisibility(false); + } } /** @@ -405,7 +424,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ enableAdaptiveBitrate(): void { - if (!this.isAdaptiveBitrateEnabled()) { + if (this._shaka && !this.isAdaptiveBitrateEnabled()) { this._trigger(BaseMediaSourceAdapter.CustomEvents.ABR_MODE_CHANGED, {mode: 'auto'}); this._shaka.configure({abr: {enabled: true}}); } @@ -418,8 +437,11 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ isAdaptiveBitrateEnabled(): boolean { - let shakaConfig = this._shaka.getConfiguration(); - return shakaConfig.abr.enabled; + if (this._shaka) { + let shakaConfig = this._shaka.getConfiguration(); + return shakaConfig.abr.enabled; + } + return false; } /** @@ -429,7 +451,9 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ seekToLiveEdge(): void { - this._videoElement.currentTime = this._shaka.seekRange().end; + if (this._shaka) { + this._videoElement.currentTime = this._shaka.seekRange().end; + } } /** @@ -439,7 +463,10 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ isLive(): boolean { - return this._shaka.isLive(); + if (this._shaka) { + return this._shaka.isLive(); + } + return false; } /** @@ -485,7 +512,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ get currentTime(): number { - if (this.isLive()) { + if (this._shaka && this.isLive()) { return this._videoElement.currentTime - this._shaka.seekRange().start; } else { return super.currentTime; @@ -499,7 +526,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @returns {void} */ set currentTime(to: number): void { - if (this.isLive()) { + if (this._shaka && this.isLive()) { this._videoElement.currentTime = this._shaka.seekRange().start + to; } else { super.currentTime = to; @@ -512,7 +539,7 @@ export default class DashAdapter extends BaseMediaSourceAdapter { * @public */ get duration(): number { - if (this.isLive()) { + if (this._shaka && this.isLive()) { let seekRange = this._shaka.seekRange(); return seekRange.end - seekRange.start; } else { diff --git a/test/src/dash-adapter.spec.js b/test/src/dash-adapter.spec.js index e6939791..2883f273 100644 --- a/test/src/dash-adapter.spec.js +++ b/test/src/dash-adapter.spec.js @@ -144,35 +144,6 @@ describe('DashAdapter: id', () => { }); }); -describe('DashAdapter: constructor', () => { - let video, dashInstance, config; - - before(() => { - video = document.createElement('video'); - config = {playback: {options: {html5: {dash: {}}}}}; - }); - - after(() => { - TestUtils.removeVideoElementsFromTestPage(); - }); - - beforeEach(() => { - dashInstance = DashAdapter.createAdapter(video, {url: ''}, config); - }); - - afterEach(() => { - dashInstance.destroy(); - dashInstance = null; - }); - - it('should create all dash adapter properties', () => { - dashInstance._shaka.should.exist; - dashInstance._config.should.exist; - dashInstance._videoElement.should.exist; - dashInstance._sourceObj.should.exist; - }); -}); - describe('DashAdapter: load', () => { let video, dashInstance, config; @@ -190,6 +161,16 @@ describe('DashAdapter: load', () => { TestUtils.removeVideoElementsFromTestPage(); }); + it('should create all dash adapter properties', () => { + dashInstance = DashAdapter.createAdapter(video, vodSource, config); + dashInstance.load().then(() => { + dashInstance._shaka.should.exist; + dashInstance._config.should.exist; + dashInstance._videoElement.should.exist; + dashInstance._sourceObj.should.exist; + }); + }); + it('should success', (done) => { dashInstance = DashAdapter.createAdapter(video, vodSource, config); dashInstance.load().then(() => { @@ -642,10 +623,12 @@ describe('DashAdapter: enableAdaptiveBitrate', () => { }); it('should enable ABR', () => { - dashInstance._shaka.getConfiguration().abr.enabled.should.be.false; - dashInstance.enableAdaptiveBitrate(); - dashInstance._shaka.getConfiguration().abr.enabled.should.be.true; - dashInstance.isAdaptiveBitrateEnabled().should.be.true; + dashInstance.load().then(() => { + dashInstance._shaka.getConfiguration().abr.enabled.should.be.false; + dashInstance.enableAdaptiveBitrate(); + dashInstance._shaka.getConfiguration().abr.enabled.should.be.true; + dashInstance.isAdaptiveBitrateEnabled().should.be.true; + }); }); it('should fire abr mode changed event', (done) => {