diff --git a/static/script-tests/tests/devices/mediaplayer/cehtmlcommontests.js b/static/script-tests/tests/devices/mediaplayer/cehtmlcommontests.js index 3f284f22..2537567e 100644 --- a/static/script-tests/tests/devices/mediaplayer/cehtmlcommontests.js +++ b/static/script-tests/tests/devices/mediaplayer/cehtmlcommontests.js @@ -195,6 +195,13 @@ window.commonTests.mediaPlayer.cehtml.mixinTests = function (testCase, mediaPlay deviceMockingHooks.finishBuffering(self._mediaPlayer); }; + var getToPlayingInLive = function (self, MediaPlayer, startTime) { + self._mediaPlayer.setSource(MediaPlayer.TYPE.LIVE_VIDEO, 'testURL', 'video/mp4'); + self._mediaPlayer.beginPlaybackFrom(startTime); + deviceMockingHooks.sendMetadata(self._mediaPlayer, 0, { start: 0, end: 100 }); + deviceMockingHooks.finishBuffering(self._mediaPlayer); + }; + var getToPlayingAtEnd = function (self, MediaPlayer) { getToPlaying(self, MediaPlayer); fakeCEHTMLObject.playPosition = 100000; @@ -1430,6 +1437,38 @@ window.commonTests.mediaPlayer.cehtml.mixinTests = function (testCase, mediaPlay }); }; + mixins.testSeekSentinelDoesNotFireInLiveWhenDeviceJumpsBackLessThanThirtySeconds = function(queue) { + expectAsserts(1); + var self = this; + runMediaPlayerTest(this, queue, function (MediaPlayer) { + getToPlayingInLive(self, MediaPlayer, 29.9); + fakeCEHTMLObject.playPosition = 0; + + var eventHandler = this.sandbox.stub(); + this._mediaPlayer.addEventCallback(null, eventHandler); + + fireSentinels(self); + + assertEventTypeHasNotBeenFired(eventHandler, MediaPlayer.EVENT.SENTINEL_SEEK); + }); + }; + + mixins.testSeekSentinelFiresInLiveWhenDeviceJumpsBackMoreThanThirtySeconds = function(queue) { + expectAsserts(1); + var self = this; + runMediaPlayerTest(this, queue, function (MediaPlayer) { + getToPlayingInLive(self, MediaPlayer, 30.1); + fakeCEHTMLObject.playPosition = 0; + + var eventHandler = this.sandbox.stub(); + this._mediaPlayer.addEventCallback(null, eventHandler); + + fireSentinels(self); + + assertEventTypeHasFired(eventHandler, MediaPlayer.EVENT.SENTINEL_SEEK); + }); + }; + mixins.testWhenBeginPlaybackFromGetsClampedFromStoppedADebugMessageIsLogged = function(queue) { expectAsserts(1); runMediaPlayerTest(this, queue, function (MediaPlayer) { diff --git a/static/script-tests/tests/devices/mediaplayer/html5commontests.js b/static/script-tests/tests/devices/mediaplayer/html5commontests.js index c9616eeb..01622e12 100644 --- a/static/script-tests/tests/devices/mediaplayer/html5commontests.js +++ b/static/script-tests/tests/devices/mediaplayer/html5commontests.js @@ -220,6 +220,13 @@ window.commonTests.mediaPlayer.html5.mixinTests = function (testCase, mediaPlaye deviceMockingHooks.finishBuffering(self._mediaPlayer); }; + var getToPlayingInLive = function (self, MediaPlayer, startTime) { + self._mediaPlayer.setSource(MediaPlayer.TYPE.LIVE_VIDEO, 'testURL', 'video/mp4'); + self._mediaPlayer.beginPlaybackFrom(startTime); + deviceMockingHooks.sendMetadata(self._mediaPlayer, 0, { start: 0, end: 100 }); + deviceMockingHooks.finishBuffering(self._mediaPlayer); + }; + var getToPlayingAtEnd = function (self, MediaPlayer) { getToPlaying(self, MediaPlayer, 98); @@ -1589,6 +1596,34 @@ window.commonTests.mediaPlayer.html5.mixinTests = function (testCase, mediaPlaye }); }; + mixins.testSeekSentinelDoesNotFireInLiveWhenDeviceJumpsBackLessThanThirtySeconds = function(queue) { + expectAsserts(1); + var self = this; + runMediaPlayerTest(this, queue, function (MediaPlayer) { + getToPlayingInLive(self, MediaPlayer, 29.9); + setPlayTimeToZero(self); + + clearEvents(self); + fireSentinels(self); + + assertNoEvent(self, MediaPlayer.EVENT.SENTINEL_SEEK); + }); + }; + + mixins.testSeekSentinelFiresInLiveWhenDeviceJumpsBackMoreThanThirtySeconds = function(queue) { + expectAsserts(1); + var self = this; + runMediaPlayerTest(this, queue, function (MediaPlayer) { + getToPlayingInLive(self, MediaPlayer, 30.1); + setPlayTimeToZero(self); + + clearEvents(self); + fireSentinels(self); + + assertEvent(self, MediaPlayer.EVENT.SENTINEL_SEEK); + }); + }; + mixins.testPauseSentinelRetriesPauseIfPauseFails = function(queue) { expectAsserts(3); var self = this; diff --git a/static/script-tests/tests/devices/mediaplayer/live/restartable.js b/static/script-tests/tests/devices/mediaplayer/live/restartable.js index 820c73ec..c23ff0c5 100644 --- a/static/script-tests/tests/devices/mediaplayer/live/restartable.js +++ b/static/script-tests/tests/devices/mediaplayer/live/restartable.js @@ -35,6 +35,8 @@ }; var config = {"modules":{"base":"antie/devices/browserdevice","modifiers":["antie/devices/mediaplayer/html5"]}, "input":{"map":{}},"layouts":[{"width":960,"height":540,"module":"fixtures/layouts/default","classes":["browserdevice540p"]}],"deviceConfigurationKey":"devices-html5-1"}; + var configWithForceBeginPlaybackToEndOfWindowAsTrue = {"modules":{"base":"antie/devices/browserdevice","modifiers":["antie/devices/mediaplayer/html5"]}, "input":{"map":{}},"layouts":[{"width":960,"height":540,"module":"fixtures/layouts/default","classes":["browserdevice540p"]}],"deviceConfigurationKey":"devices-html5-1", "forceBeginPlaybackToEndOfWindow": true}; + var configWithForceBeginPlaybackToEndOfWindowAsFalse = {"modules":{"base":"antie/devices/browserdevice","modifiers":["antie/devices/mediaplayer/html5"]}, "input":{"map":{}},"layouts":[{"width":960,"height":540,"module":"fixtures/layouts/default","classes":["browserdevice540p"]}],"deviceConfigurationKey":"devices-html5-1", "forceBeginPlaybackToEndOfWindow": false}; this.LivePlayerSupportLevelRestartableTest.prototype.testGetLiveSupportReturnsRestartableWithSupportLevelRestartable = function (queue) { expectAsserts(1); @@ -170,4 +172,49 @@ assertEquals(playerElement, livePlayer.getPlayerElement()); }, config); }; + + this.LivePlayerSupportLevelRestartableTest.prototype.testBeginPlaybackFromIsCalledWithInfinityIfForceBeginPlaybackToEndOfWindowIsTrue = function (queue) { + expectAsserts(2); + queuedApplicationInit(queue, 'lib/mockapplication', ["antie/devices/mediaplayer/mediaplayer", "antie/devices/device", "antie/devices/mediaplayer/live/restartable"], function (application, MediaPlayer, Device) { + var device = new Device(antie.framework.deviceConfiguration); + var livePlayer = device.getLivePlayer(); + + livePlayer._mediaPlayer.beginPlayback = this.sandbox.stub(); + livePlayer._mediaPlayer.beginPlaybackFrom = this.sandbox.stub(); + + livePlayer.beginPlayback(); + assert(livePlayer._mediaPlayer.beginPlaybackFrom.calledWith(Infinity)); + assert(livePlayer._mediaPlayer.beginPlayback.notCalled); + }, configWithForceBeginPlaybackToEndOfWindowAsTrue); + }; + + this.LivePlayerSupportLevelRestartableTest.prototype.testBeginPlaybackIsCalledIfForceBeginPlaybackToEndOfWindowIsFalse = function (queue) { + expectAsserts(2); + queuedApplicationInit(queue, 'lib/mockapplication', ["antie/devices/mediaplayer/mediaplayer", "antie/devices/device", "antie/devices/mediaplayer/live/restartable"], function (application, MediaPlayer, Device) { + var device = new Device(antie.framework.deviceConfiguration); + var livePlayer = device.getLivePlayer(); + + livePlayer._mediaPlayer.beginPlayback = this.sandbox.stub(); + livePlayer._mediaPlayer.beginPlaybackFrom = this.sandbox.stub(); + + livePlayer.beginPlayback(); + assert(livePlayer._mediaPlayer.beginPlayback.called); + assert(livePlayer._mediaPlayer.beginPlaybackFrom.notCalled); + }, configWithForceBeginPlaybackToEndOfWindowAsFalse); + }; + + this.LivePlayerSupportLevelRestartableTest.prototype.testBeginPlaybackIsCalledIfForceBeginPlaybackToEndOfWindowIsNotPresent = function (queue) { + expectAsserts(2); + queuedApplicationInit(queue, 'lib/mockapplication', ["antie/devices/mediaplayer/mediaplayer", "antie/devices/device", "antie/devices/mediaplayer/live/restartable"], function (application, MediaPlayer, Device) { + var device = new Device(antie.framework.deviceConfiguration); + var livePlayer = device.getLivePlayer(); + + livePlayer._mediaPlayer.beginPlayback = this.sandbox.stub(); + livePlayer._mediaPlayer.beginPlaybackFrom = this.sandbox.stub(); + + livePlayer.beginPlayback(); + assert(livePlayer._mediaPlayer.beginPlayback.called); + assert(livePlayer._mediaPlayer.beginPlaybackFrom.notCalled); + }, config); + }; })(); diff --git a/static/script-tests/tests/devices/mediaplayer/live/seekable.js b/static/script-tests/tests/devices/mediaplayer/live/seekable.js index f4cafaf5..9e8bcd08 100644 --- a/static/script-tests/tests/devices/mediaplayer/live/seekable.js +++ b/static/script-tests/tests/devices/mediaplayer/live/seekable.js @@ -35,6 +35,9 @@ }; var config = {"modules":{"base":"antie/devices/browserdevice","modifiers":["antie/devices/mediaplayer/html5"]}, "input":{"map":{}},"layouts":[{"width":960,"height":540,"module":"fixtures/layouts/default","classes":["browserdevice540p"]}],"deviceConfigurationKey":"devices-html5-1"}; + var configWithForceBeginPlaybackToEndOfWindowAsTrue = {"modules":{"base":"antie/devices/browserdevice","modifiers":["antie/devices/mediaplayer/html5"]}, "input":{"map":{}},"layouts":[{"width":960,"height":540,"module":"fixtures/layouts/default","classes":["browserdevice540p"]}],"deviceConfigurationKey":"devices-html5-1", "forceBeginPlaybackToEndOfWindow": true}; + var configWithForceBeginPlaybackToEndOfWindowAsFalse = {"modules":{"base":"antie/devices/browserdevice","modifiers":["antie/devices/mediaplayer/html5"]}, "input":{"map":{}},"layouts":[{"width":960,"height":540,"module":"fixtures/layouts/default","classes":["browserdevice540p"]}],"deviceConfigurationKey":"devices-html5-1", "forceBeginPlaybackToEndOfWindow": false}; + this.LivePlayerSupportLevelSeekableTest.prototype.testGetLiveSupportReturnsSeekableWithSupportLevelSeekable = function (queue) { expectAsserts(1); @@ -193,4 +196,49 @@ assertEquals(playerElement, livePlayer.getPlayerElement()); }, config); }; + + this.LivePlayerSupportLevelSeekableTest.prototype.testBeginPlaybackFromIsCalledWithInfinityIfForceBeginPlaybackToEndOfWindowIsTrue = function (queue) { + expectAsserts(2); + queuedApplicationInit(queue, 'lib/mockapplication', ["antie/devices/mediaplayer/mediaplayer", "antie/devices/device", "antie/devices/mediaplayer/live/seekable"], function (application, MediaPlayer, Device) { + var device = new Device(antie.framework.deviceConfiguration); + var livePlayer = device.getLivePlayer(); + + livePlayer._mediaPlayer.beginPlayback = this.sandbox.stub(); + livePlayer._mediaPlayer.beginPlaybackFrom = this.sandbox.stub(); + + livePlayer.beginPlayback(); + assert(livePlayer._mediaPlayer.beginPlaybackFrom.calledWith(Infinity)); + assert(livePlayer._mediaPlayer.beginPlayback.notCalled); + }, configWithForceBeginPlaybackToEndOfWindowAsTrue); + }; + + this.LivePlayerSupportLevelSeekableTest.prototype.testBeginPlaybackIsCalledIfForceBeginPlaybackToEndOfWindowIsFalse = function (queue) { + expectAsserts(2); + queuedApplicationInit(queue, 'lib/mockapplication', ["antie/devices/mediaplayer/mediaplayer", "antie/devices/device", "antie/devices/mediaplayer/live/seekable"], function (application, MediaPlayer, Device) { + var device = new Device(antie.framework.deviceConfiguration); + var livePlayer = device.getLivePlayer(); + + livePlayer._mediaPlayer.beginPlayback = this.sandbox.stub(); + livePlayer._mediaPlayer.beginPlaybackFrom = this.sandbox.stub(); + + livePlayer.beginPlayback(); + assert(livePlayer._mediaPlayer.beginPlayback.called); + assert(livePlayer._mediaPlayer.beginPlaybackFrom.notCalled); + }, configWithForceBeginPlaybackToEndOfWindowAsFalse); + }; + + this.LivePlayerSupportLevelSeekableTest.prototype.testBeginPlaybackIsCalledIfForceBeginPlaybackToEndOfWindowIsNotPresent = function (queue) { + expectAsserts(2); + queuedApplicationInit(queue, 'lib/mockapplication', ["antie/devices/mediaplayer/mediaplayer", "antie/devices/device", "antie/devices/mediaplayer/live/seekable"], function (application, MediaPlayer, Device) { + var device = new Device(antie.framework.deviceConfiguration); + var livePlayer = device.getLivePlayer(); + + livePlayer._mediaPlayer.beginPlayback = this.sandbox.stub(); + livePlayer._mediaPlayer.beginPlaybackFrom = this.sandbox.stub(); + + livePlayer.beginPlayback(); + assert(livePlayer._mediaPlayer.beginPlayback.called); + assert(livePlayer._mediaPlayer.beginPlaybackFrom.notCalled); + }, config); + }; })(); diff --git a/static/script/devices/mediaplayer/cehtml.js b/static/script/devices/mediaplayer/cehtml.js index 35d2e085..e9c65cb4 100644 --- a/static/script/devices/mediaplayer/cehtml.js +++ b/static/script/devices/mediaplayer/cehtml.js @@ -60,6 +60,7 @@ require.def( this._source = url; this._mimeType = mimeType; this._timeAtLastSenintelInterval = 0; + this._setSeekSentinelTolerance(); this._createElement(); this._addElementToDOM(); this._mediaElement.data = this._source; @@ -584,12 +585,11 @@ require.def( return false; } - var SEEK_TOLERANCE = 15; var currentTime = this.getCurrentTime(); var clampedSentinelSeekTime = this._getClampedTime(this._sentinelSeekTime); - var sentinelSeekRequired = Math.abs(clampedSentinelSeekTime - currentTime) > SEEK_TOLERANCE; + var sentinelSeekRequired = Math.abs(clampedSentinelSeekTime - currentTime) > this._seekSentinelTolerance; var sentinelActionTaken = false; if (sentinelSeekRequired) { @@ -644,6 +644,16 @@ require.def( } return false; + }, + + _setSeekSentinelTolerance: function() { + var ON_DEMAND_SEEK_SENTINEL_TOLERANCE = 15; + var LIVE_SEEK_SENTINEL_TOLERANCE = 30; + + this._seekSentinelTolerance = ON_DEMAND_SEEK_SENTINEL_TOLERANCE; + if (this._isLiveMedia()) { + this._seekSentinelTolerance = LIVE_SEEK_SENTINEL_TOLERANCE; + } } }); diff --git a/static/script/devices/mediaplayer/html5.js b/static/script/devices/mediaplayer/html5.js index 8a610ac5..7bda86f7 100644 --- a/static/script/devices/mediaplayer/html5.js +++ b/static/script/devices/mediaplayer/html5.js @@ -68,6 +68,8 @@ require.def( idSuffix = "Audio"; } + this._setSeekSentinelTolerance(); + this._mediaElement = device._createElement(idSuffix.toLowerCase(), "mediaPlayer" + idSuffix); this._mediaElement.autoplay = false; this._mediaElement.style.position = "absolute"; @@ -644,7 +646,7 @@ require.def( var currentTime = this.getCurrentTime(); var sentinelActionTaken = false; - if (Math.abs(currentTime - this._sentinelSeekTime) > 15) { + if (Math.abs(currentTime - this._sentinelSeekTime) > this._seekSentinelTolerance) { sentinelActionTaken = this._nextSentinelAttempt(this._sentinelLimits.seek, function() { self._mediaElement.currentTime = self._sentinelSeekTime; }); @@ -736,6 +738,16 @@ require.def( return this._readyToPlayFrom; } return false; + }, + + _setSeekSentinelTolerance: function() { + var ON_DEMAND_SEEK_SENTINEL_TOLERANCE = 15; + var LIVE_SEEK_SENTINEL_TOLERANCE = 30; + + this._seekSentinelTolerance = ON_DEMAND_SEEK_SENTINEL_TOLERANCE; + if (this._isLiveMedia()) { + this._seekSentinelTolerance = LIVE_SEEK_SENTINEL_TOLERANCE; + } } }); diff --git a/static/script/devices/mediaplayer/live/restartable.js b/static/script/devices/mediaplayer/live/restartable.js index 1aac5592..aeb76bde 100644 --- a/static/script/devices/mediaplayer/live/restartable.js +++ b/static/script/devices/mediaplayer/live/restartable.js @@ -56,7 +56,12 @@ require.def( }, beginPlayback: function() { - this._mediaPlayer.beginPlayback(); + var config = RuntimeContext.getDevice().getConfig(); + if (config && config.forceBeginPlaybackToEndOfWindow) { + this._mediaPlayer.beginPlaybackFrom(Infinity); + } else { + this._mediaPlayer.beginPlayback(); + } }, beginPlaybackFrom: function(offset) { diff --git a/static/script/devices/mediaplayer/live/seekable.js b/static/script/devices/mediaplayer/live/seekable.js index c880e964..cc556124 100644 --- a/static/script/devices/mediaplayer/live/seekable.js +++ b/static/script/devices/mediaplayer/live/seekable.js @@ -60,7 +60,12 @@ require.def( }, beginPlayback: function() { - this._mediaPlayer.beginPlayback(); + var config = RuntimeContext.getDevice().getConfig(); + if (config && config.forceBeginPlaybackToEndOfWindow) { + this._mediaPlayer.beginPlaybackFrom(Infinity); + } else { + this._mediaPlayer.beginPlayback(); + } }, beginPlaybackFrom: function(offset) {