diff --git a/src/engines/html5/html5.js b/src/engines/html5/html5.js index ca78eea96..70e494b7a 100644 --- a/src/engines/html5/html5.js +++ b/src/engines/html5/html5.js @@ -196,7 +196,7 @@ export default class Html5 extends FakeEventTarget implements IEngine { this._eventManager.listen(this._mediaSourceAdapter, CustomEventType.ABR_MODE_CHANGED, (event: FakeEvent) => this.dispatchEvent(event)); this._eventManager.listen(this._mediaSourceAdapter, CustomEventType.TEXT_CUE_CHANGED, (event: FakeEvent) => this.dispatchEvent(event)); this._eventManager.listen(this._mediaSourceAdapter, Html5EventType.ERROR, (event: FakeEvent) => this.dispatchEvent(event)); - this._eventManager.listen(this._mediaSourceAdapter, Html5EventType.DURATION_CHANGE, (event: FakeEvent) => this.dispatchEvent(event)); + this._eventManager.listen(this._mediaSourceAdapter, Html5EventType.TIME_UPDATE, (event: FakeEvent) => this.dispatchEvent(event)); this._eventManager.listen(this._mediaSourceAdapter, Html5EventType.PLAYING, (event: FakeEvent) => this.dispatchEvent(event)); } } diff --git a/src/engines/html5/media-source/adapters/native-adapter.js b/src/engines/html5/media-source/adapters/native-adapter.js index 8de8ec842..3b59da0f9 100644 --- a/src/engines/html5/media-source/adapters/native-adapter.js +++ b/src/engines/html5/media-source/adapters/native-adapter.js @@ -775,7 +775,7 @@ export default class NativeAdapter extends BaseMediaSourceAdapter { const liveEdge = this._getLiveEdge(); if (this._liveEdge !== liveEdge) { this._liveEdge = liveEdge; - this._trigger(Html5EventType.DURATION_CHANGE, {}); + this._videoElement.dispatchEvent(new window.Event(Html5EventType.DURATION_CHANGE)); } }, 2000); } @@ -795,7 +795,7 @@ export default class NativeAdapter extends BaseMediaSourceAdapter { * @public */ getStartTimeOfDvrWindow(): number { - if (this.isLive()) { + if (this.isLive() && this._videoElement.seekable.length) { return this._videoElement.seekable.start(0); } else { return 0; diff --git a/src/engines/html5/media-source/base-media-source-adapter.js b/src/engines/html5/media-source/base-media-source-adapter.js index f97cd9dc7..aa071463c 100644 --- a/src/engines/html5/media-source/base-media-source-adapter.js +++ b/src/engines/html5/media-source/base-media-source-adapter.js @@ -73,6 +73,7 @@ export default class BaseMediaSourceAdapter extends FakeEventTarget implements I this._videoElement = videoElement; this._sourceObj = source; this._config = config; + this._handleLiveTimeUpdate(); } /** @@ -105,10 +106,10 @@ export default class BaseMediaSourceAdapter extends FakeEventTarget implements I /** * Dispatch an adapter event forward. * @param {string} name - The name of the event. - * @param {Object} payload - The event payload. + * @param {?Object} payload - The event payload. * @returns {void} */ - _trigger(name: string, payload: Object): void { + _trigger(name: string, payload?: Object): void { this.dispatchEvent(new FakeEvent(name, payload)); } @@ -158,6 +159,20 @@ export default class BaseMediaSourceAdapter extends FakeEventTarget implements I return BaseMediaSourceAdapter._throwNotImplementedError('isLive'); } + /** + * Handling live time update (as is not triggered when video is paused, but the current time changed) + * @function _handleLiveTimeUpdate + * @returns {void} + * @private + */ + _handleLiveTimeUpdate(): void { + this._videoElement.addEventListener(Html5EventType.DURATION_CHANGE, () => { + if (this.isLive() && this._videoElement.paused) { + this._trigger(Html5EventType.TIME_UPDATE); + } + }); + } + get src(): string { return BaseMediaSourceAdapter._throwNotImplementedError('get src'); } diff --git a/test/src/engines/html5/media-source/adapters/native-adapter.spec.js b/test/src/engines/html5/media-source/adapters/native-adapter.spec.js index 2be6f07fe..8e4a9233e 100644 --- a/test/src/engines/html5/media-source/adapters/native-adapter.spec.js +++ b/test/src/engines/html5/media-source/adapters/native-adapter.spec.js @@ -708,7 +708,35 @@ describe('NativeAdapter: _handleLiveDurationChange', () => { it('should trigger durationchange for live', (done) => { nativeInstance = NativeAdapter.createAdapter(video, sourcesConfig.Live.hls[0], {sources: {}}); nativeInstance.load().then(() => { - nativeInstance.addEventListener('durationchange', () => { + nativeInstance._videoElement.addEventListener('durationchange', () => { + done(); + }); + }).catch(() => { + done(); + }); + }); +}); + +describe('NativeAdapter: _handleLiveTimeUpdate', () => { + let video, nativeInstance; + + beforeEach(() => { + video = document.createElement("video"); + }); + + afterEach(() => { + nativeInstance.destroy(); + nativeInstance = null; + }); + + after(() => { + removeVideoElementsFromTestPage(); + }); + + it('should trigger timeupdate for live when paused', (done) => { + nativeInstance = NativeAdapter.createAdapter(video, sourcesConfig.Live.hls[0], {sources: {}}); + nativeInstance.load().then(() => { + nativeInstance.addEventListener('timeupdate', () => { done(); }); }).catch(() => {