From 6f988e8b7325e4e19219f8501be24fa9d5eaf62c Mon Sep 17 00:00:00 2001 From: Tom Sadler Date: Wed, 28 Jun 2017 13:02:47 +0100 Subject: [PATCH 1/4] Update range on BUFFERING_COMPLETE. BUFFERING_COMPLETE is observed to fire before STREAM_INFO_READY, resulting in the initial PLAYING being sent without range or duration set. This changes fixes it. --- .../devices/mediaplayer/samsung_streaming.js | 152 ++++++++++-------- .../devices/mediaplayer/samsung_streaming.js | 37 +++-- 2 files changed, 103 insertions(+), 86 deletions(-) diff --git a/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js b/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js index 269196fa..830e248f 100644 --- a/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js +++ b/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js @@ -146,7 +146,7 @@ self.sandbox.stub(self._device, 'getScreenSize').returns(screenSize); self._errorLog = self.sandbox.stub(self._device.getLogger(), 'error'); self._mediaPlayer = self._device.getMediaPlayer(); - + action.call(self, MediaPlayer); }, config); }; @@ -154,7 +154,7 @@ //--------------------- // Samsung Streaming specific tests //--------------------- - + var listenerEventCodes = { CONNECTION_FAILED : 1, AUTHENTICATION_FAILED : 2, @@ -174,7 +174,7 @@ this.SamsungStreamingMediaPlayerTests.prototype.testSamsungMapleListenerFunctionsAddedDuringSetSource = function(queue) { expectAsserts(2); runMediaPlayerTest(this, queue, function(MediaPlayer) { - + assertUndefined('Expecting playerPlaugin.OnEvent to be undefined', playerPlugin.OnEvent); this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testURL', 'video/mp4'); @@ -220,7 +220,7 @@ assertUndefined(playerPlugin['OnEvent']); this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testURL', 'video/mp4'); - + assertFunction(playerPlugin['OnEvent']); }); }; @@ -256,8 +256,8 @@ }); }; - - + + /*HLS specific tests START*/ this.SamsungStreamingMediaPlayerTests.prototype.testPLayerOpenPluginThenHlsStartPlaybackCalledOnDeviceWhenBeginPlaybackFromCalledInStoppedState = function(queue) { expectAsserts(9); @@ -269,7 +269,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL|COMPONENT=HLS')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlaybackFrom(0); assert(playerPlugin._methods.StartPlayback.calledWith(0)); @@ -286,7 +286,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL|COMPONENT=HLS')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlayback(); assert(playerPlugin._methods.StartPlayback.calledOnce); @@ -303,12 +303,12 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL|HLSSLIDING|COMPONENT=HLS')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlaybackFrom(0); assert(playerPlugin._methods.StartPlayback.calledOnce); }); - }; + }; this.SamsungStreamingMediaPlayerTests.prototype.testStreamingPLayerOpenPluginThenHlsLivePlayCalledOnDeviceWhenBeginPlaybackFromCalledInStoppedState = function(queue) { expectAsserts(8); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -319,7 +319,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL|HLSSLIDING|COMPONENT=HLS')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlayback(); assert(playerPlugin._methods.StartPlayback.calledOnce); @@ -336,7 +336,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL|HLSSLIDING|COMPONENT=HLS')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlaybackFrom(0); assert(playerPlugin._methods.StartPlayback.calledOnce); @@ -344,7 +344,7 @@ assertEquals(this._mediaPlayer.CLAMP_OFFSET_FROM_START_OF_RANGE, playerPlugin._methods.StartPlayback.args[0][0]); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testHlsLiveResumePlayCalledWithTimePassedIntoBeginPlaybackFrom = function(queue) { expectAsserts(9); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -355,14 +355,14 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL|HLSSLIDING|COMPONENT=HLS')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlaybackFrom(19); assert(playerPlugin._methods.StartPlayback.calledWith(19)); assert(playerPlugin._methods.StartPlayback.calledOnce); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testHlsGetPlayingRangeUpdateCalledBeforeJumpForward = function (queue) { expectAsserts(8); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -374,18 +374,18 @@ playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 0); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); this._mediaPlayer._updatingTime = false; - + assert(playerPlugin._methods.InitPlayer.calledOnce); assert(playerPlugin._methods.StartPlayback.calledOnce); assert(playerPlugin._methods.GetPlayingRange.calledOnce); - + playerPlugin._range = { start: 24, end: 124 }; playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 22 * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); - + assert(playerPlugin._methods.JumpForward.notCalled); this._mediaPlayer.playFrom(50); assertEquals(this._mediaPlayer_range, playerPlugin._methods.GetPlayingRange.args[1][0]); @@ -393,7 +393,7 @@ assert(playerPlugin._methods.JumpForward.calledOnce); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testHlsGetPlayingRangeUpdateCalledBeforeJumpBackward = function (queue) { expectAsserts(8); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -405,18 +405,18 @@ playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 90 * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); this._mediaPlayer._updatingTime = false; - + assert(playerPlugin._methods.InitPlayer.calledOnce); assert(playerPlugin._methods.StartPlayback.calledOnce); assert(playerPlugin._methods.GetPlayingRange.calledOnce); - + playerPlugin._range = { start: 24, end: 124 }; playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 122 * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); - + assert(playerPlugin._methods.JumpBackward.notCalled); this._mediaPlayer.playFrom(10); assertEquals(this._mediaPlayer_range, playerPlugin._methods.GetPlayingRange.args[1][0]); @@ -424,7 +424,7 @@ assert(playerPlugin._methods.JumpBackward.calledOnce); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testHlsGetPlayingRangeUpdateNotCalledWhileInRangeTolerance = function (queue) { expectAsserts(6); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -434,20 +434,20 @@ deviceMockingHooks.sendMetadata(this._mediaPlayer, 100, { start: 0, end: 100 }); deviceMockingHooks.finishBuffering(this._mediaPlayer); playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 100 * 1000); - + assert(playerPlugin._methods.InitPlayer.calledOnce); assert(playerPlugin._methods.StartPlayback.calledOnce); assert(playerPlugin._methods.GetPlayingRange.calledOnce); - + this._mediaPlayer.playFrom(10); assert(playerPlugin._methods.GetPlayingRange.calledOnce); - + this._mediaPlayer._updatingTime = false; this._mediaPlayer.playFrom(20); assert(playerPlugin._methods.GetPlayingRange.calledTwice); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testHlsGetPlayingRangeUpdateOnCurrentTimeGreaterThanEndRangeTolerance = function (queue) { expectAsserts(4); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -457,23 +457,23 @@ playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 100 * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); deviceMockingHooks.finishBuffering(this._mediaPlayer); - + assert(playerPlugin._methods.GetPlayingRange.calledOnce); this._mediaPlayer._updatingTime = false; - + this._mediaPlayer._range = { start: 24, end: 124 }; playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 133 * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); - + assertEquals(this._mediaPlayer_range, playerPlugin._methods.GetPlayingRange.args[1][0]); assert(playerPlugin._methods.GetPlayingRange.calledTwice); assert(playerPlugin._methods.JumpBackward.notCalled); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testHlsGetPlayingRangeUpdateOnCurrentTimeLowerThanStartRangeTolerance = function (queue) { expectAsserts(4); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -483,24 +483,24 @@ deviceMockingHooks.finishBuffering(this._mediaPlayer); playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, this._mediaPlayer.CLAMP_OFFSET_FROM_END_OF_RANGE * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); - + assert(playerPlugin._methods.GetPlayingRange.calledOnce); this._mediaPlayer._updatingTime = false; - + this._mediaPlayer._range = { start: 24, end: 124 }; playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 15 * 1000); playerPlugin._methods.GetPlayingRange.returns(playerPlugin._range.start + '-' + playerPlugin._range.end); - + assertEquals(this._mediaPlayer_range, playerPlugin._methods.GetPlayingRange.args[1][0]); assert(playerPlugin._methods.GetPlayingRange.calledTwice); assert(playerPlugin._methods.JumpForward.notCalled); }); }; /*HLS specific tests END*/ - + this.SamsungStreamingMediaPlayerTests.prototype.testSetSourceInitPlayerFailsReturningZero = function(queue) { var initPlayerReturnCode = 0; doTestSetSourceInitPlayerFailsStartPlybackNotCalled(this, queue, initPlayerReturnCode); @@ -522,15 +522,15 @@ var eventHandler = self.sandbox.stub(); self._mediaPlayer.addEventCallback(null, eventHandler); playerPlugin._methods.InitPlayer.returns(initPlayerReturnCode); - + try { self._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); self._mediaPlayer.beginPlayback(); - } catch (e) {} - + } catch (e) {} + assert(playerPlugin._methods.InitPlayer.calledOnce); assert(playerPlugin._methods.StartPlayback.notCalled); - + assert(eventHandler.calledTwice); assertEquals(MediaPlayer.EVENT.ERROR, eventHandler.args[1][0].type); assertEquals('Failed to initialize video: testUrl', eventHandler.args[1][0].errorMessage); @@ -547,7 +547,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlaybackFrom(0); assert(playerPlugin._methods.StartPlayback.calledWith(0)); @@ -565,7 +565,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlayback(); assert(playerPlugin._methods.StartPlayback.calledOnce); @@ -598,7 +598,7 @@ assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testURL')); assert(playerPlugin._methods.InitPlayer.calledOnce); - + assert(playerPlugin._methods.StartPlayback.notCalled); this._mediaPlayer.beginPlaybackFrom(19); assert(playerPlugin._methods.StartPlayback.calledWith(19)); @@ -633,7 +633,7 @@ runMediaPlayerTest(this, queue, function(MediaPlayer) { this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); this._mediaPlayer.beginPlaybackFrom(0); - + assert(playerPlugin._methods.InitPlayer.calledOnce); assert(playerPlugin._methods.InitPlayer.calledWith('testUrl')); assert(playerPlugin._methods.StartPlayback.calledOnce); @@ -767,7 +767,7 @@ assert(playerPlugin._methods.JumpBackward.calledWith(30)); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testPlayFromEarlierTimeWhenPlayingThenPlayFromWhileBufferingSeeksAndPlays = function(queue) { expectAsserts(14); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -789,16 +789,16 @@ assertEquals(MediaPlayer.STATE.BUFFERING, this._mediaPlayer.getState()); assert(playerPlugin._methods.JumpBackward.calledOnce); assert(playerPlugin._methods.JumpBackward.calledWith(30)); - + this._mediaPlayer.playFrom(10); assert(playerPlugin._methods.JumpBackward.calledOnce); assertEquals(MediaPlayer.STATE.BUFFERING, this._mediaPlayer.getState()); playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 20000); deviceMockingHooks.finishBuffering(this._mediaPlayer); - + assert(playerPlugin._methods.JumpBackward.calledTwice); assertEquals(10, playerPlugin._methods.JumpBackward.args[1][0]); - + deviceMockingHooks.finishBuffering(this._mediaPlayer); playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 10000); assertEquals(MediaPlayer.STATE.PLAYING, this._mediaPlayer.getState()); @@ -935,7 +935,7 @@ assertEquals(MediaPlayer.STATE.PAUSED, this._mediaPlayer.getState()); assert(playerPlugin._methods.Resume.notCalled); - + this._mediaPlayer.resume(); assert(playerPlugin._methods.Resume.calledOnce); @@ -1010,7 +1010,7 @@ var eventHandler = this.sandbox.stub(); this._mediaPlayer.addEventCallback(null, eventHandler); - + playerPlugin.OnEvent(listenerEventCodes.RENDER_ERROR); var expectedError = 'Media element emitted OnRenderError'; @@ -1187,7 +1187,7 @@ playerPlugin._methods.GetDuration.returns(playerPlugin._range.end * 1000); deviceMockingHooks.sendMetadata(this._mediaPlayer, 0, { start: 0, end: 60 }); deviceMockingHooks.finishBuffering(this._mediaPlayer); - + deviceMockingHooks.reachEndOfMedia(this._mediaPlayer); this._mediaPlayer.playFrom(100); @@ -1251,7 +1251,7 @@ this._mediaPlayer.addEventCallback(null, callback); playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 10000); - + assert(callback.calledOnce); assertEquals(10, callback.args[0][0].currentTime); @@ -1476,7 +1476,7 @@ assert(playerPlugin._methods.Stop.calledOnce); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testMediaPlayerIgnorePeriodicRenderingCompleteEventInCompleteState = function (queue) { expectAsserts(4); runMediaPlayerTest(this, queue, function(MediaPlayer) { @@ -1485,55 +1485,55 @@ deviceMockingHooks.sendMetadata(this._mediaPlayer, 0, { start: 0, end: 60 }); deviceMockingHooks.finishBuffering(this._mediaPlayer); playerPlugin.OnEvent(listenerEventCodes.CURRENT_PLAYBACK_TIME, 0); - + var eventHandler = this.sandbox.stub(); this._mediaPlayer.addEventCallback(null, eventHandler); - + assert(eventHandler.notCalled); deviceMockingHooks.reachEndOfMedia(this._mediaPlayer); assertEquals(MediaPlayer.EVENT.COMPLETE, eventHandler.args[1][0].type); assert(eventHandler.calledTwice); - + //if Stop() is not called after RENDERING_COMPLETE then player sends periodically BUFFERING_COMPLETE and RENDERING_COMPLETE //ignore BUFFERING_COMPLETE and RENDERING_COMPLETE if player is already in COMPLETE state playerPlugin.OnEvent(listenerEventCodes.BUFFERING_COMPLETE); playerPlugin.OnEvent(listenerEventCodes.RENDERING_COMPLETE); - + assert(eventHandler.calledTwice); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testPluginCloseCalledOnReset = function(queue) { expectAsserts(6); runMediaPlayerTest(this, queue, function(MediaPlayer) { - assert(playerPlugin.Open.notCalled); + assert(playerPlugin.Open.notCalled); this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); assert(playerPlugin.Open.calledOnce); - - assert(playerPlugin.Close.notCalled); + + assert(playerPlugin.Close.notCalled); this._mediaPlayer.reset(); assert(playerPlugin.Close.calledOnce); - + this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); assert(playerPlugin.Close.calledOnce); - assert(playerPlugin.Open.calledTwice); + assert(playerPlugin.Open.calledTwice); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testPluginCloseNotCalledAfterStopCalledThenStartPlayback = function(queue) { expectAsserts(7); runMediaPlayerTest(this, queue, function(MediaPlayer) { - assert(playerPlugin.Open.notCalled); + assert(playerPlugin.Open.notCalled); this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); this._mediaPlayer.beginPlayback(); assert(playerPlugin.Open.calledOnce); - + this._mediaPlayer.stop(); assert(playerPlugin.Close.notCalled); - + this._mediaPlayer.beginPlayback(); assert(playerPlugin.Close.notCalled); - assert(playerPlugin.Open.calledOnce); + assert(playerPlugin.Open.calledOnce); assert(playerPlugin._methods.InitPlayer.calledOnce); assert(playerPlugin._methods.StartPlayback.calledTwice); }); @@ -1609,6 +1609,20 @@ }); }; + this.SamsungStreamingMediaPlayerTests.prototype.testRangeIsUpdatedByBufferingCompleteEvents = function(queue) { + runMediaPlayerTest(this, queue, function(MediaPlayer) { + this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); + this._mediaPlayer.beginPlaybackFrom(0); + playerPlugin._methods.GetPlayingRange.returns('0-60'); + playerPlugin._methods.GetDuration.returns(60 * 1000); + deviceMockingHooks.finishBuffering(this._mediaPlayer); + + assertEquals(MediaPlayer.STATE.PLAYING, this._mediaPlayer.getState()); + assertEquals(60, this._mediaPlayer.getDuration()); + assertEquals({ start: 0, end: 60 }, this._mediaPlayer.getSeekableRange()); + }); + }; + this.SamsungStreamingMediaPlayerTests.prototype.testFailedJumpReturningZeroWhilePlayingReturnsToPlayingState = function(queue) { var jumpReturnCode = 0; doTestFailedJumpWhilePlayingReturnsToPlayingState(this, queue, jumpReturnCode); @@ -1868,7 +1882,7 @@ this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testUrl', 'testMimeType'); this._mediaPlayer.beginPlaybackFrom(0); this._mediaPlayer.pause(); - + deviceMockingHooks.sendMetadata(this._mediaPlayer, 30, { start: 0, end: 60 }); deviceMockingHooks.finishBuffering(this._mediaPlayer); @@ -1909,7 +1923,7 @@ assert(playerPlugin._methods.InitPlayer.calledWith('test/url|COMPONENT=HLS')); }); }; - + this.SamsungStreamingMediaPlayerTests.prototype.testMediaUrlGetsSpecialHlsLiveFragmentAppended = function(queue) { expectAsserts(1); runMediaPlayerTest(this, queue, function(MediaPlayer) { diff --git a/static/script/devices/mediaplayer/samsung_streaming.js b/static/script/devices/mediaplayer/samsung_streaming.js index 2cdf109f..328ea49e 100644 --- a/static/script/devices/mediaplayer/samsung_streaming.js +++ b/static/script/devices/mediaplayer/samsung_streaming.js @@ -61,7 +61,7 @@ require.def( this._currentTimeKnown = false; this._updatingTime = false; this._lastWindowRanged = false; - + try { this._registerSamsungPlugins(); } catch (ignoreErr) { @@ -111,7 +111,7 @@ require.def( self.tvmwPlugin.SetSource(self.originalSource); }, false); }, - + _openPlayerPlugin : function() { if (this._currentPlayer !== undefined) { this._playerPlugin.Close(); @@ -119,7 +119,7 @@ require.def( this._playerPlugin.Open('Player', '1.010', 'Player'); this._currentPlayer = this.PlayerEmps.Player; }, - + _openStreamingPlayerPlugin : function() { if (this._currentPlayer !== undefined) { this._playerPlugin.Close(); @@ -127,7 +127,7 @@ require.def( this._playerPlugin.Open('StreamingPlayer', '1.0', 'StreamingPlayer'); this._currentPlayer = this.PlayerEmps.StreamingPlayer; }, - + _closePlugin: function() { this._playerPlugin.Close(); this._currentPlayer = undefined; @@ -135,7 +135,7 @@ require.def( _initPlayer: function(source) { var result = this._playerPlugin.Execute('InitPlayer', source); - + if (result !== 1) { this._toError('Failed to initialize video: ' + this._source); } @@ -174,8 +174,8 @@ require.def( */ playFrom: function (seconds) { this._postBufferingState = MediaPlayer.STATE.PLAYING; - var seekingTo = this._range ? this._getClampedTimeForPlayFrom(seconds) : seconds; - + var seekingTo = this._range ? this._getClampedTimeForPlayFrom(seconds) : seconds; + switch (this.getState()) { case MediaPlayer.STATE.BUFFERING: // this._deferSeekingTo = seekingTo; @@ -243,7 +243,7 @@ require.def( beginPlaybackFrom: function(seconds) { this._postBufferingState = MediaPlayer.STATE.PLAYING; var seekingTo = this.getSeekableRange() ? this._getClampedTimeForPlayFrom(seconds) : seconds; - + //StartPlayback from live position 0 causes spoiler defect if (seekingTo === 0 && this._isLiveMedia()) { seekingTo = this.CLAMP_OFFSET_FROM_START_OF_RANGE; @@ -364,7 +364,7 @@ require.def( } return undefined; }, - + _isLiveRangeOutdated: function () { var time = Math.floor(this._currentTime); if (time % 8 === 0 && !this._updatingTime && this._lastWindowRanged !== time) { @@ -403,7 +403,7 @@ require.def( if (this.getState() !== MediaPlayer.STATE.BUFFERING) { return; } - + if (!this._isInitialBufferingFinished() && this._nextSeekingTo !== null) { this._deferSeekingTo = this._nextSeekingTo; this._nextSeekingTo = null; @@ -438,7 +438,7 @@ require.def( this._currentTimeKnown = false; }, - _tryPauseWithStateTransition: function() { + _tryPauseWithStateTransition: function() { var success = this._playerPlugin.Execute('Pause'); success = success && (success !== -1); @@ -455,7 +455,7 @@ require.def( this._emitEvent(MediaPlayer.EVENT.STATUS); } }, - + _updateRange: function () { var self = this; if (this._currentPlayer === this.PlayerEmps.StreamingPlayer) { @@ -491,7 +491,7 @@ require.def( this._range.start += 8; this._range.end += 8; } - + if (this._nextSeekingTo !== null) { this._deferSeekingTo = this._nextSeekingTo; this._nextSeekingTo = null; @@ -531,7 +531,7 @@ require.def( } return clampedTime; }, - + _getClampOffsetFromConfig: function() { var clampOffsetFromEndOfRange; var config = RuntimeContext.getDevice().getConfig(); @@ -583,6 +583,9 @@ require.def( break; case self.PlayerEventCodes.BUFFERING_COMPLETE: + if (!self._updatingTime) { + self._updateRange(); + } //[optimisation] if Stop() is not called after RENDERING_COMPLETE then player sends periodically BUFFERING_COMPLETE and RENDERING_COMPLETE //ignore BUFFERING_COMPLETE if player is already in COMPLETE state if (self.getState() !== MediaPlayer.STATE.COMPLETE) { @@ -684,7 +687,7 @@ require.def( var mime = this._mimeType.toLowerCase(); return mime === 'application/vnd.apple.mpegurl' || mime === 'application/x-mpegurl'; }, - + _isCurrentTimeInRangeTolerance: function (seconds) { if (seconds > this._range.end + this.RANGE_UPDATE_TOLERANCE) { return false; @@ -694,7 +697,7 @@ require.def( return true; } }, - + _isInitialBufferingFinished: function () { if (this._currentTime === undefined || this._currentTime === 0) { return false; @@ -772,4 +775,4 @@ require.def( return Player; } -); \ No newline at end of file +); From 3ad0e8222adfa1a2c01575533951028924b0db6b Mon Sep 17 00:00:00 2001 From: Tom Sadler Date: Wed, 28 Jun 2017 13:21:58 +0100 Subject: [PATCH 2/4] Clamp start of range for all values lower than clamp value, not just 0. --- .../devices/mediaplayer/samsung_streaming.js | 19 +++++++++++++++++++ .../devices/mediaplayer/samsung_streaming.js | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js b/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js index 830e248f..ef406a90 100644 --- a/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js +++ b/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js @@ -345,6 +345,25 @@ }); }; + this.SamsungStreamingMediaPlayerTests.prototype.testHlsLiveStartPlaybackFromNearStartUsesClampOffsetFromStartOfRange = function(queue) { + expectAsserts(9); + runMediaPlayerTest(this, queue, function(MediaPlayer) { + assert(playerPlugin.Open.notCalled); + assert(playerPlugin._methods.InitPlayer.notCalled); + this._mediaPlayer.setSource(MediaPlayer.TYPE.LIVE_VIDEO, 'testURL', 'application/vnd.apple.mpegurl'); + assert(playerPlugin.Open.calledWith('StreamingPlayer', '1.0', 'StreamingPlayer')); + assert(playerPlugin.Open.calledOnce); + assert(playerPlugin._methods.InitPlayer.calledWith('testURL|HLSSLIDING|COMPONENT=HLS')); + assert(playerPlugin._methods.InitPlayer.calledOnce); + + assert(playerPlugin._methods.StartPlayback.notCalled); + this._mediaPlayer.beginPlaybackFrom(0.1); + assert(playerPlugin._methods.StartPlayback.calledOnce); + //live playback started from 0 position causes spoiler defect + assertEquals(this._mediaPlayer.CLAMP_OFFSET_FROM_START_OF_RANGE, playerPlugin._methods.StartPlayback.args[0][0]); + }); + }; + this.SamsungStreamingMediaPlayerTests.prototype.testHlsLiveResumePlayCalledWithTimePassedIntoBeginPlaybackFrom = function(queue) { expectAsserts(9); runMediaPlayerTest(this, queue, function(MediaPlayer) { diff --git a/static/script/devices/mediaplayer/samsung_streaming.js b/static/script/devices/mediaplayer/samsung_streaming.js index 328ea49e..94e3eb34 100644 --- a/static/script/devices/mediaplayer/samsung_streaming.js +++ b/static/script/devices/mediaplayer/samsung_streaming.js @@ -245,7 +245,7 @@ require.def( var seekingTo = this.getSeekableRange() ? this._getClampedTimeForPlayFrom(seconds) : seconds; //StartPlayback from live position 0 causes spoiler defect - if (seekingTo === 0 && this._isLiveMedia()) { + if (seekingTo < this.CLAMP_OFFSET_FROM_START_OF_RANGE && this._isLiveMedia()) { seekingTo = this.CLAMP_OFFSET_FROM_START_OF_RANGE; } else { seekingTo = parseInt(Math.floor(seekingTo), 10); From a2fb309777e5b5fefb5fd61f80f86f7e0f4384f9 Mon Sep 17 00:00:00 2001 From: Tom Sadler Date: Wed, 28 Jun 2017 13:41:04 +0100 Subject: [PATCH 3/4] GetPlayingRange should only be used for live HLS; GetDuration should be used in all other circumstances. --- .../devices/mediaplayer/samsung_streaming.js | 17 +++++++++++++++-- .../devices/mediaplayer/samsung_streaming.js | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js b/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js index ef406a90..2b427016 100644 --- a/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js +++ b/static/script-tests/tests/devices/mediaplayer/samsung_streaming.js @@ -259,7 +259,7 @@ /*HLS specific tests START*/ - this.SamsungStreamingMediaPlayerTests.prototype.testPLayerOpenPluginThenHlsStartPlaybackCalledOnDeviceWhenBeginPlaybackFromCalledInStoppedState = function(queue) { + this.SamsungStreamingMediaPlayerTests.prototype.testPlayerOpenPluginThenHlsStartPlaybackCalledOnDeviceWhenBeginPlaybackFromCalledInStoppedState = function(queue) { expectAsserts(9); runMediaPlayerTest(this, queue, function(MediaPlayer) { assert(playerPlugin.Open.notCalled); @@ -276,7 +276,7 @@ assert(playerPlugin._methods.StartPlayback.calledOnce); }); }; - this.SamsungStreamingMediaPlayerTests.prototype.testPLayerOpenPluginThenHlsPlayCalledOnDeviceWhenBeginPlaybackFromCalledInStoppedState = function(queue) { + this.SamsungStreamingMediaPlayerTests.prototype.testPlayerOpenPluginThenHlsPlayCalledOnDeviceWhenBeginPlaybackFromCalledInStoppedState = function(queue) { expectAsserts(8); runMediaPlayerTest(this, queue, function(MediaPlayer) { assert(playerPlugin.Open.notCalled); @@ -518,6 +518,19 @@ assert(playerPlugin._methods.JumpForward.notCalled); }); }; + + this.SamsungStreamingMediaPlayerTests.prototype.testHlsVodGetDurationUsedInsteadOfGetPlayingRange = function (queue) { + expectAsserts(4); + runMediaPlayerTest(this, queue, function(MediaPlayer) { + this._mediaPlayer.setSource(MediaPlayer.TYPE.VIDEO, 'testURL', 'application/vnd.apple.mpegurl'); + this._mediaPlayer.beginPlaybackFrom(0); + deviceMockingHooks.sendMetadata(this._mediaPlayer, 0, { start: 0, end: 100 }); + + assert(playerPlugin._methods.GetPlayingRange.notCalled); + assert(playerPlugin._methods.GetDuration.calledOnce); + assertEquals(100, this._mediaPlayer.getDuration()); + }); + }; /*HLS specific tests END*/ this.SamsungStreamingMediaPlayerTests.prototype.testSetSourceInitPlayerFailsReturningZero = function(queue) { diff --git a/static/script/devices/mediaplayer/samsung_streaming.js b/static/script/devices/mediaplayer/samsung_streaming.js index 94e3eb34..73ff0dea 100644 --- a/static/script/devices/mediaplayer/samsung_streaming.js +++ b/static/script/devices/mediaplayer/samsung_streaming.js @@ -458,7 +458,7 @@ require.def( _updateRange: function () { var self = this; - if (this._currentPlayer === this.PlayerEmps.StreamingPlayer) { + if (this._isHlsMimeType() && this._isLiveMedia()) { var range = this._playerPlugin.Execute('GetPlayingRange').split('-'); this._range = { start: Math.floor(range[0]), @@ -469,7 +469,7 @@ require.def( setTimeout(function () { self._updatingTime = false; }, self.RANGE_UPDATE_TOLERANCE * 1000); - } else if (this._currentPlayer === this.PlayerEmps.Player) { + } else { var duration = this._playerPlugin.Execute('GetDuration')/1000; this._range = { start: 0, From cc2414c4ecf7c46bed1925f9889f20fdc8fa251c Mon Sep 17 00:00:00 2001 From: Tom Sadler Date: Thu, 29 Jun 2017 13:38:41 +0100 Subject: [PATCH 4/4] Improve comments. --- static/script/devices/mediaplayer/samsung_streaming.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/script/devices/mediaplayer/samsung_streaming.js b/static/script/devices/mediaplayer/samsung_streaming.js index 73ff0dea..9321a43e 100644 --- a/static/script/devices/mediaplayer/samsung_streaming.js +++ b/static/script/devices/mediaplayer/samsung_streaming.js @@ -244,7 +244,7 @@ require.def( this._postBufferingState = MediaPlayer.STATE.PLAYING; var seekingTo = this.getSeekableRange() ? this._getClampedTimeForPlayFrom(seconds) : seconds; - //StartPlayback from live position 0 causes spoiler defect + //StartPlayback from near start of range causes spoiler defect if (seekingTo < this.CLAMP_OFFSET_FROM_START_OF_RANGE && this._isLiveMedia()) { seekingTo = this.CLAMP_OFFSET_FROM_START_OF_RANGE; } else { @@ -583,6 +583,7 @@ require.def( break; case self.PlayerEventCodes.BUFFERING_COMPLETE: + // For live HLS, don't update the range more than once every 8 seconds if (!self._updatingTime) { self._updateRange(); }