bigscreen-player
Advanced tools
Comparing version 1.0.6 to 1.1.0
{ | ||
"name": "bigscreen-player", | ||
"version": "1.0.6", | ||
"version": "1.1.0", | ||
"description": "Simplified media playback for bigscreen devices.", | ||
@@ -5,0 +5,0 @@ "main": "script/bigscreenplayer.js", |
require( | ||
[ | ||
'bigscreenplayer/bigscreenplayer', | ||
'squire', | ||
'bigscreenplayer/models/mediastate', | ||
@@ -8,5 +8,5 @@ 'bigscreenplayer/models/windowtypes', | ||
'bigscreenplayer/pluginenums', | ||
'bigscreenplayer/playbackstrategy/mockstrategy' | ||
'bigscreenplayer/plugins' | ||
], | ||
function (BigscreenPlayer, MediaState, WindowTypes, PauseTriggers, PluginEnums, MockStrategy) { | ||
function (Squire, MediaState, WindowTypes, PauseTriggers, PluginEnums, Plugins) { | ||
var MediaPlayerLiveSupport = { | ||
@@ -18,7 +18,18 @@ NONE: 'none', | ||
}; | ||
var bigscreenPlayer = BigscreenPlayer(); | ||
var injector = new Squire(); | ||
var bigscreenPlayer; | ||
var bigscreenPlayerData; | ||
var playbackElement; | ||
var mockStrategy = MockStrategy(); | ||
var manifestParserMock; | ||
var mockEventHook; | ||
var mockPlayerComponentInstance = jasmine.createSpyObj('playerComponentMock', [ | ||
'play', 'pause', 'isEnded', 'isPaused', 'setCurrentTime', 'getCurrentTime', 'getDuration', 'getSeekableRange', | ||
'getPlayerElement', 'isSubtitlesAvailable', 'isSubtitlesEnabled', 'setSubtitlesEnabled', 'tearDown']); | ||
var mockPlayerComponent = function (playbackElement, bigscreenPlayerData, windowType, enableSubtitles, callback, device) { | ||
mockEventHook = callback; | ||
return mockPlayerComponentInstance; | ||
}; | ||
function initialiseBigscreenPlayer (options) { | ||
@@ -42,8 +53,11 @@ // options = subtitlesAvailable, windowType, windowStartTime, windowEndTime | ||
type: 'mimeType', | ||
bitrate: 'bitrate' | ||
bitrate: 'bitrate', | ||
manifest: options.manifest, | ||
manifestType: options.manifestType | ||
}, | ||
serverDate: options.serverDate, | ||
initialPlaybackTime: options.initialPlaybackTime | ||
}; | ||
if (windowType === WindowTypes.SLIDING) { | ||
if (windowType === WindowTypes.SLIDING && options.manifest === undefined) { | ||
bigscreenPlayerData.time = { | ||
@@ -63,10 +77,22 @@ windowStartTime: options.windowStartTime !== undefined ? options.windowStartTime : 724000, | ||
describe('Bigscreen Player', function () { | ||
var mockPlugin; | ||
beforeEach(function () { | ||
mockPlugin = jasmine.createSpyObj('plugin', ['onError', 'onFatalError', 'onErrorHandled', 'onErrorCleared', 'onBufferingCleared', 'onBuffering']); | ||
beforeEach(function (done) { | ||
manifestParserMock = jasmine.createSpyObj('manifestParserSpy', ['parse']); | ||
injector.mock({ | ||
'bigscreenplayer/parsers/manifestparser': function () { return manifestParserMock; }, | ||
'bigscreenplayer/playercomponent': mockPlayerComponent, | ||
'bigscreenplayer/plugins': Plugins | ||
}); | ||
injector.require(['bigscreenplayer/bigscreenplayer'], function (bigscreenPlayerReference) { | ||
bigscreenPlayer = bigscreenPlayerReference(); | ||
done(); | ||
}); | ||
}); | ||
afterEach(function () { | ||
Object.keys(mockPlayerComponentInstance).forEach(function (spyFunction) { | ||
mockPlayerComponentInstance[spyFunction].calls.reset(); | ||
}); | ||
bigscreenPlayer.tearDown(); | ||
mockPlugin = undefined; | ||
}); | ||
@@ -80,3 +106,3 @@ | ||
it('should set endOfStream to true when playing live and no initial playback time is set', function () { | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(30); | ||
mockPlayerComponentInstance.getCurrentTime.and.returnValue(30); | ||
@@ -88,3 +114,3 @@ var callback = jasmine.createSpy(); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: 30}, timeUpdate: true, isBufferingTimeoutError: false}); | ||
@@ -95,3 +121,3 @@ expect(callback).toHaveBeenCalledWith({currentTime: 30, endOfStream: true}); | ||
it('should set endOfStream to false when playing live and initialPlaybackTime is 0', function () { | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(0); | ||
mockPlayerComponentInstance.getCurrentTime.and.returnValue(0); | ||
@@ -104,3 +130,3 @@ var callback = jasmine.createSpy('listenerSimulcast'); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: 0}, timeUpdate: true, isBufferingTimeoutError: false}); | ||
@@ -117,3 +143,3 @@ expect(callback).toHaveBeenCalledWith({currentTime: 0, endOfStream: false}); | ||
spyOn(mockStrategy, 'getPlayerElement').and.returnValue(mockedVideo); | ||
mockPlayerComponentInstance.getPlayerElement.and.returnValue(mockedVideo); | ||
@@ -135,7 +161,7 @@ bigscreenPlayer.getPlayerElement(); | ||
it('should fire the callback when a state event comes back from the strategy', function () { | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PLAYING); | ||
mockEventHook({data: {state: MediaState.PLAYING}}); | ||
expect(callback).toHaveBeenCalledWith({state: MediaState.PLAYING, endOfStream: false}); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.WAITING); | ||
mockEventHook({data: {state: MediaState.WAITING}}); | ||
@@ -146,6 +172,5 @@ expect(callback).toHaveBeenCalledWith({state: MediaState.WAITING, endOfStream: false}); | ||
it('should set the pause trigger to the one set when a pause event comes back from strategy', function () { | ||
// set pause trigger to PauseTriggers.USER | ||
bigscreenPlayer.pause(); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PAUSED); | ||
mockEventHook({data: {state: MediaState.PAUSED}}); | ||
@@ -156,3 +181,3 @@ expect(callback).toHaveBeenCalledWith({state: MediaState.PAUSED, trigger: PauseTriggers.USER, endOfStream: false}); | ||
it('should set the pause trigger to device when a pause event comes back from strategy and a trigger is not set', function () { | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PAUSED); | ||
mockEventHook({data: {state: MediaState.PAUSED}}); | ||
@@ -163,13 +188,5 @@ expect(callback).toHaveBeenCalledWith({state: MediaState.PAUSED, trigger: PauseTriggers.DEVICE, endOfStream: false}); | ||
it('should set isBufferingTimeoutError when a fatal error event comes back from strategy', function () { | ||
jasmine.clock().install(); | ||
mockEventHook({data: {state: MediaState.FATAL_ERROR}, isBufferingTimeoutError: false}); | ||
mockStrategy.mockingHooks.fireErrorEvent({errorProperties: {}}); | ||
// five second timeout in playerComponent that triggers attemptCdnFailover, | ||
// if only one cdn exists then it fires a fatal error. | ||
jasmine.clock().tick(5000); | ||
expect(callback).toHaveBeenCalledWith({state: MediaState.FATAL_ERROR, isBufferingTimeoutError: false, endOfStream: false}); | ||
jasmine.clock().uninstall(); | ||
}); | ||
@@ -196,7 +213,7 @@ | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PLAYING); | ||
mockEventHook({data: {state: MediaState.PLAYING}}); | ||
bigscreenPlayer.unregisterForStateChanges(listener2); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PLAYING); | ||
mockEventHook({data: {state: MediaState.PLAYING}}); | ||
@@ -217,3 +234,3 @@ expect(listener1).toHaveBeenCalledTimes(2); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PLAYING); | ||
mockEventHook({data: {state: MediaState.PLAYING}}); | ||
@@ -226,4 +243,2 @@ expect(listener1).toHaveBeenCalledWith({state: MediaState.PLAYING, endOfStream: false}); | ||
it('should call the callback when we get a timeupdate event from the strategy', function () { | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(60); | ||
var callback = jasmine.createSpy('listener1'); | ||
@@ -235,3 +250,3 @@ initialiseBigscreenPlayer(); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: 60}, timeUpdate: true}); | ||
@@ -261,7 +276,7 @@ expect(callback).toHaveBeenCalledWith({currentTime: 60, endOfStream: false}); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: 0}, timeUpdate: true}); | ||
bigscreenPlayer.unregisterForTimeUpdates(listener2); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: 1}, timeUpdate: true}); | ||
@@ -274,4 +289,2 @@ expect(listener1).toHaveBeenCalledTimes(2); | ||
it('should only remove existing callbacks from timeUpdateCallbacks', function () { | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(60); | ||
initialiseBigscreenPlayer(); | ||
@@ -285,3 +298,3 @@ | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: 60}, timeUpdate: true}); | ||
@@ -294,4 +307,2 @@ expect(listener1).toHaveBeenCalledWith({currentTime: 60, endOfStream: false}); | ||
it('should setCurrentTime on the strategy/playerComponent', function () { | ||
spyOn(mockStrategy, 'setCurrentTime'); | ||
initialiseBigscreenPlayer(); | ||
@@ -301,15 +312,16 @@ | ||
expect(mockStrategy.setCurrentTime).toHaveBeenCalledWith(60); | ||
expect(mockPlayerComponentInstance.setCurrentTime).toHaveBeenCalledWith(60); | ||
}); | ||
it('should not set current time on the strategy/playerComponent if bigscreen player is not initialised', function () { | ||
spyOn(mockStrategy, 'setCurrentTime'); | ||
bigscreenPlayer.setCurrentTime(60); | ||
expect(mockStrategy.setCurrentTime).not.toHaveBeenCalled(); | ||
expect(mockPlayerComponentInstance.setCurrentTime).not.toHaveBeenCalled(); | ||
}); | ||
it('should set endOfStream to true when seeking to the end of a simulcast', function () { | ||
initialiseBigscreenPlayer({windowType: WindowTypes.SLIDING}); | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 10, windowEndTime: 100, correction: 0}); | ||
initialiseBigscreenPlayer({windowType: WindowTypes.SLIDING, manifest: {}, manifestType: 'mpd'}); | ||
var callback = jasmine.createSpy(); | ||
@@ -320,8 +332,8 @@ var endOfStreamWindow = bigscreenPlayerData.time.windowEndTime - 2; | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: bigscreenPlayerData.time.windowStartTime, end: bigscreenPlayerData.time.windowEndTime}); | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(endOfStreamWindow); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: bigscreenPlayerData.time.windowStartTime, end: bigscreenPlayerData.time.windowEndTime}); | ||
mockPlayerComponentInstance.getCurrentTime.and.returnValue(endOfStreamWindow); | ||
bigscreenPlayer.setCurrentTime(endOfStreamWindow); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: endOfStreamWindow}, timeUpdate: true}); | ||
@@ -339,8 +351,8 @@ expect(callback).toHaveBeenCalledWith({currentTime: endOfStreamWindow, endOfStream: true}); | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: bigscreenPlayerData.time.windowStartTime, end: bigscreenPlayerData.time.windowEndTime}); | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(middleOfStreamWindow); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: bigscreenPlayerData.time.windowStartTime, end: bigscreenPlayerData.time.windowEndTime}); | ||
mockPlayerComponentInstance.getCurrentTime.and.returnValue(middleOfStreamWindow); | ||
bigscreenPlayer.setCurrentTime(middleOfStreamWindow); | ||
mockStrategy.mockingHooks.fireTimeUpdate(); | ||
mockEventHook({data: {currentTime: middleOfStreamWindow}, timeUpdate: true}); | ||
@@ -355,3 +367,3 @@ expect(callback).toHaveBeenCalledWith({currentTime: middleOfStreamWindow, endOfStream: false}); | ||
spyOn(mockStrategy, 'getCurrentTime').and.returnValue(10); | ||
mockPlayerComponentInstance.getCurrentTime.and.returnValue(10); | ||
@@ -386,3 +398,3 @@ expect(bigscreenPlayer.getCurrentTime()).toBe(10); | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: 0, end: 10}); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: 0, end: 10}); | ||
@@ -398,2 +410,27 @@ expect(bigscreenPlayer.getSeekableRange().start).toEqual(0); | ||
describe('getLiveWindowData', function () { | ||
it('should return undefined values when windowType is static', function () { | ||
initialiseBigscreenPlayer({windowType: WindowTypes.STATIC}); | ||
expect(bigscreenPlayer.getLiveWindowData()).toEqual({}); | ||
}); | ||
it('should return liveWindowData when the windowType is sliding and manifest is provided', function () { | ||
var mockLiveData = {windowStartTime: 1, windowEndTime: 2}; | ||
manifestParserMock.parse.and.returnValue(mockLiveData); | ||
var initialisationData = {windowType: WindowTypes.SLIDING, manifest: true, serverDate: new Date(), initialPlaybackTime: new Date().getTime()}; | ||
initialiseBigscreenPlayer(initialisationData); | ||
expect(bigscreenPlayer.getLiveWindowData()).toEqual({windowStartTime: 1, windowEndTime: 2, serverDate: initialisationData.serverDate, initialPlaybackTime: initialisationData.initialPlaybackTime}); | ||
}); | ||
it('should return a subset of liveWindowData when the windowType is sliding and time block is provided', function () { | ||
var initialisationData = {windowType: WindowTypes.SLIDING, windowStartTime: 1, windowEndTime: 2, initialPlaybackTime: new Date().getTime()}; | ||
initialiseBigscreenPlayer(initialisationData); | ||
expect(bigscreenPlayer.getLiveWindowData()).toEqual({serverDate: undefined, windowStartTime: 1, windowEndTime: 2, initialPlaybackTime: initialisationData.initialPlaybackTime}); | ||
}); | ||
}); | ||
describe('getDuration', function () { | ||
@@ -403,3 +440,3 @@ it('should get the duration from the strategy', function () { | ||
spyOn(mockStrategy, 'getDuration').and.returnValue(10); | ||
mockPlayerComponentInstance.getDuration.and.returnValue(10); | ||
@@ -418,3 +455,3 @@ expect(bigscreenPlayer.getDuration()).toEqual(10); | ||
spyOn(mockStrategy, 'isPaused').and.returnValue(true); | ||
mockPlayerComponentInstance.isPaused.and.returnValue(true); | ||
@@ -433,3 +470,3 @@ expect(bigscreenPlayer.isPaused()).toBe(true); | ||
spyOn(mockStrategy, 'isEnded').and.returnValue(true); | ||
mockPlayerComponentInstance.isEnded.and.returnValue(true); | ||
@@ -448,7 +485,5 @@ expect(bigscreenPlayer.isEnded()).toBe(true); | ||
spyOn(mockStrategy, 'play'); | ||
bigscreenPlayer.play(); | ||
expect(mockStrategy.play).toHaveBeenCalledWith(); | ||
expect(mockPlayerComponentInstance.play).toHaveBeenCalledWith(); | ||
}); | ||
@@ -463,7 +498,5 @@ }); | ||
spyOn(mockStrategy, 'pause'); | ||
bigscreenPlayer.pause(opts); | ||
expect(mockStrategy.pause).toHaveBeenCalledWith(jasmine.objectContaining({disableAutoResume: true})); | ||
expect(mockPlayerComponentInstance.pause).toHaveBeenCalledWith(jasmine.objectContaining({disableAutoResume: true})); | ||
}); | ||
@@ -482,3 +515,3 @@ | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PAUSED); | ||
mockEventHook({data: {state: MediaState.PAUSED}}); | ||
@@ -499,3 +532,3 @@ expect(callback).toHaveBeenCalledWith(jasmine.objectContaining({trigger: PauseTriggers.APP})); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PAUSED); | ||
mockEventHook({data: {state: MediaState.PAUSED}}); | ||
@@ -510,11 +543,9 @@ expect(callback).toHaveBeenCalledWith(jasmine.objectContaining({trigger: PauseTriggers.USER})); | ||
expect(bigscreenPlayer.isSubtitlesEnabled()).toBe(false); | ||
bigscreenPlayer.setSubtitlesEnabled(true); | ||
expect(bigscreenPlayer.isSubtitlesEnabled()).toBe(true); | ||
expect(mockPlayerComponentInstance.setSubtitlesEnabled).toHaveBeenCalledWith(true); | ||
bigscreenPlayer.setSubtitlesEnabled(false); | ||
expect(bigscreenPlayer.isSubtitlesEnabled()).toBe(false); | ||
expect(mockPlayerComponentInstance.setSubtitlesEnabled).toHaveBeenCalledWith(false); | ||
}); | ||
@@ -524,12 +555,8 @@ }); | ||
describe('isSubtitlesEnabled', function () { | ||
it('should return true when setup with subtitles', function () { | ||
initialiseBigscreenPlayer({ subtitlesAvailable: true, subtitlesEnabled: true }); | ||
it('calls through to playerComponent isSubtitlesEnabled when called', function () { | ||
initialiseBigscreenPlayer(); | ||
expect(bigscreenPlayer.isSubtitlesEnabled()).toBe(true); | ||
}); | ||
bigscreenPlayer.isSubtitlesEnabled(); | ||
it('should return false if not specified on setup', function () { | ||
initialiseBigscreenPlayer({ subtitlesAvailable: true }); | ||
expect(bigscreenPlayer.isSubtitlesEnabled()).toBe(false); | ||
expect(mockPlayerComponentInstance.isSubtitlesEnabled).toHaveBeenCalled(); | ||
}); | ||
@@ -539,12 +566,8 @@ }); | ||
describe('isSubtitlesAvailable', function () { | ||
it('should return true when subtitles are available', function () { | ||
initialiseBigscreenPlayer({ subtitlesAvailable: true }); | ||
it('calls through to playerComponent isSubtitlesAvailable when called', function () { | ||
initialiseBigscreenPlayer(); | ||
expect(bigscreenPlayer.isSubtitlesAvailable()).toBe(true); | ||
}); | ||
bigscreenPlayer.isSubtitlesAvailable(); | ||
it('should return false when subtitles are not available', function () { | ||
initialiseBigscreenPlayer({ subtitlesAvailable: false }); | ||
expect(bigscreenPlayer.isSubtitlesAvailable()).toBe(false); | ||
expect(mockPlayerComponentInstance.isSubtitlesAvailable).toHaveBeenCalled(); | ||
}); | ||
@@ -562,5 +585,10 @@ }); | ||
it('should return true when it can seek', function () { | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: 0, end: 60}); | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 0, windowEndTime: 150000000, correction: 0}); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: 0, end: 60}); | ||
initialiseBigscreenPlayer({windowType: WindowTypes.SLIDING, liveSupport: MediaPlayerLiveSupport.SEEKABLE}); | ||
initialiseBigscreenPlayer({windowType: WindowTypes.SLIDING, | ||
liveSupport: MediaPlayerLiveSupport.SEEKABLE, | ||
manifest: {}, | ||
manifestType: 'mpd' | ||
}); | ||
@@ -571,3 +599,4 @@ expect(bigscreenPlayer.canSeek()).toBe(true); | ||
it('should return false when seekable range is infinite', function () { | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: 0, end: Infinity}); | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 0, windowEndTime: Infinity, correction: 0}); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: 0, end: Infinity}); | ||
@@ -580,3 +609,4 @@ initialiseBigscreenPlayer({windowType: WindowTypes.SLIDING, liveSupport: MediaPlayerLiveSupport.SEEKABLE}); | ||
it('should return false when window length less than four minutes', function () { | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: 0, end: 60}); | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 0, windowEndTime: 239999, correction: 0}); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: 0, end: 60}); | ||
@@ -594,3 +624,3 @@ initialiseBigscreenPlayer({ | ||
it('should return false when device does not support seeking', function () { | ||
spyOn(mockStrategy, 'getSeekableRange').and.returnValue({start: 0, end: 60}); | ||
mockPlayerComponentInstance.getSeekableRange.and.returnValue({start: 0, end: 60}); | ||
@@ -613,5 +643,8 @@ initialiseBigscreenPlayer({windowType: WindowTypes.SLIDING, liveSupport: MediaPlayerLiveSupport.RESTARTABLE}); | ||
it('should return true when it can pause', function () { | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 0, windowEndTime: 150000000, correction: 0}); | ||
initialiseBigscreenPlayer({ | ||
windowType: WindowTypes.SLIDING, | ||
liveSupport: MediaPlayerLiveSupport.RESTARTABLE | ||
liveSupport: MediaPlayerLiveSupport.RESTARTABLE, | ||
manifest: {}, | ||
manifestType: 'mpd' | ||
}); | ||
@@ -623,6 +656,8 @@ | ||
it('should return false when window length less than four minutes', function () { | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 0, windowEndTime: 239999, correction: 0}); | ||
initialiseBigscreenPlayer({ | ||
windowType: WindowTypes.SLIDING, | ||
windowStartTime: 0, | ||
windowEndTime: 239999, | ||
manifest: {}, | ||
manifestType: 'mpd', | ||
liveSupport: MediaPlayerLiveSupport.RESTARTABLE | ||
@@ -635,2 +670,3 @@ }); | ||
it('should return false when device does not support pausing', function () { | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 0, windowEndTime: 150000000, correction: 0}); | ||
initialiseBigscreenPlayer({ | ||
@@ -648,8 +684,10 @@ windowType: WindowTypes.SLIDING, | ||
it('converts video time to epoch time when windowStartTime is supplied', function () { | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 4200, windowEndTime: 150000000, correction: 0}); | ||
initialiseBigscreenPlayer({ | ||
windowType: WindowTypes.SLIDING, | ||
windowStartTime: 1500000000000 | ||
manifest: {}, | ||
manifestType: 'mpd' | ||
}); | ||
expect(bigscreenPlayer.convertVideoTimeSecondsToEpochMs(1000)).toBe(1500001000000); | ||
expect(bigscreenPlayer.convertVideoTimeSecondsToEpochMs(1000)).toBe(bigscreenPlayerData.time.windowStartTime + 1000000); | ||
}); | ||
@@ -664,2 +702,24 @@ | ||
describe('covertEpochMsToVideoTimeSeconds', function () { | ||
it('converts epoch time to video time when windowStartTime is available', function () { | ||
// windowStartTime - 16 January 2019 12:00:00 | ||
// windowEndTime - 16 January 2019 14:00:00 | ||
manifestParserMock.parse.and.returnValue({windowStartTime: 1547640000000, windowEndTime: 1547647200000, correction: 0}); | ||
initialiseBigscreenPlayer({ | ||
windowType: WindowTypes.SLIDING, | ||
manifest: {}, | ||
manifestType: 'mpd' | ||
}); | ||
// Time to convert - 16 January 2019 13:00:00 - one hour (3600 seconds) | ||
expect(bigscreenPlayer.convertEpochMsToVideoTimeSeconds(1547643600000)).toBe(3600); | ||
}); | ||
it('does not convert epoch time to video time when windowStartTime is not available', function () { | ||
initialiseBigscreenPlayer(); | ||
expect(bigscreenPlayer.convertEpochMsToVideoTimeSeconds(1547643600000)).toBeUndefined(); | ||
}); | ||
}); | ||
describe('registerPlugin', function () { | ||
@@ -677,61 +737,11 @@ beforeEach(function () { | ||
it('should call the plugin when we get an error from the strategy', function () { | ||
it('should register a specific plugin', function () { | ||
var mockPlugin = jasmine.createSpyObj('plugin', ['onError']); | ||
initialiseBigscreenPlayer(); | ||
bigscreenPlayer.registerPlugin(mockPlugin); | ||
mockStrategy.mockingHooks.fireErrorEvent({errorProperties: {}}); | ||
Plugins.interface.onError({errorProperties: {}}); | ||
expect(mockPlugin.onError).toHaveBeenCalledWith(jasmine.objectContaining({status: PluginEnums.STATUS.STARTED, stateType: PluginEnums.TYPE.ERROR})); | ||
expect(mockPlugin.onError).toHaveBeenCalledWith({errorProperties: {}}); | ||
}); | ||
it('should call the plugin when we fatal error', function () { | ||
initialiseBigscreenPlayer(); | ||
bigscreenPlayer.registerPlugin(mockPlugin); | ||
mockStrategy.mockingHooks.fireErrorEvent({errorProperties: {}}); | ||
jasmine.clock().tick(5000); | ||
expect(mockPlugin.onFatalError).toHaveBeenCalledWith(jasmine.objectContaining({status: PluginEnums.STATUS.FATAL, stateType: PluginEnums.TYPE.ERROR})); | ||
}); | ||
it('should call the plugin when we failover', function () { | ||
initialiseBigscreenPlayer(); | ||
bigscreenPlayerData.media.urls.push({url: 'b', cdn: 'cdn-b'}); // Add another cdn so we have one to failover too. | ||
bigscreenPlayer.registerPlugin(mockPlugin); | ||
mockStrategy.mockingHooks.fireErrorEvent({errorProperties: {}}); | ||
jasmine.clock().tick(5000); | ||
expect(mockPlugin.onErrorHandled).toHaveBeenCalledWith(jasmine.objectContaining({status: PluginEnums.STATUS.FAILOVER, stateType: PluginEnums.TYPE.ERROR})); | ||
}); | ||
it('should call the plugin when we dismiss an error', function () { | ||
initialiseBigscreenPlayer(); | ||
bigscreenPlayer.registerPlugin(mockPlugin); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PLAYING); | ||
expect(mockPlugin.onErrorCleared).toHaveBeenCalledWith(jasmine.objectContaining({status: PluginEnums.STATUS.DISMISSED, stateType: PluginEnums.TYPE.ERROR})); | ||
}); | ||
it('should call the plugin when we get a buffering event from the strategy', function () { | ||
initialiseBigscreenPlayer(); | ||
bigscreenPlayer.registerPlugin(mockPlugin); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.WAITING); | ||
expect(mockPlugin.onBuffering).toHaveBeenCalledWith(jasmine.objectContaining({status: PluginEnums.STATUS.STARTED, stateType: PluginEnums.TYPE.BUFFERING})); | ||
}); | ||
it('should call the plugin when we dismiss buffering', function () { | ||
initialiseBigscreenPlayer(); | ||
bigscreenPlayer.registerPlugin(mockPlugin); | ||
mockStrategy.mockingHooks.fireEvent(MediaState.PLAYING); | ||
expect(mockPlugin.onBufferingCleared).toHaveBeenCalledWith(jasmine.objectContaining({status: PluginEnums.STATUS.DISMISSED, stateType: PluginEnums.TYPE.BUFFERING})); | ||
}); | ||
}); | ||
@@ -753,2 +763,4 @@ | ||
jasmine.clock().uninstall(); | ||
mockPlugin.onError.calls.reset(); | ||
mockPluginTwo.onError.calls.reset(); | ||
}); | ||
@@ -759,6 +771,6 @@ | ||
mockStrategy.mockingHooks.fireErrorEvent({errorProperties: {}}); | ||
Plugins.interface.onError({errorProperties: {}}); | ||
expect(mockPlugin.onError).not.toHaveBeenCalled(); | ||
expect(mockPluginTwo.onError).toHaveBeenCalled(); | ||
expect(mockPluginTwo.onError).toHaveBeenCalledWith({errorProperties: {}}); | ||
}); | ||
@@ -769,3 +781,3 @@ | ||
mockStrategy.mockingHooks.fireErrorEvent({errorProperties: {}}); | ||
Plugins.interface.onError({errorProperties: {}}); | ||
@@ -772,0 +784,0 @@ expect(mockPlugin.onError).not.toHaveBeenCalled(); |
@@ -11,5 +11,7 @@ define('bigscreenplayer/bigscreenplayer', | ||
'bigscreenplayer/debugger/chronicle', | ||
'bigscreenplayer/debugger/debugtool' | ||
'bigscreenplayer/debugger/debugtool', | ||
'bigscreenplayer/parsers/manifestparser', | ||
'bigscreenplayer/utils/timeutils' | ||
], | ||
function (MediaState, PlayerComponent, PauseTriggers, DynamicWindowUtils, WindowTypes, MockBigscreenPlayer, Plugins, Chronicle, DebugTool) { | ||
function (MediaState, PlayerComponent, PauseTriggers, DynamicWindowUtils, WindowTypes, MockBigscreenPlayer, Plugins, Chronicle, DebugTool, ManifestParser, SlidingWindowUtils) { | ||
'use strict'; | ||
@@ -21,4 +23,6 @@ function BigscreenPlayer () { | ||
var mediaKind; | ||
var liveWindowStart; | ||
var liveWindowEnd; | ||
var windowStartTime; | ||
var windowEndTime; | ||
var initialPlaybackTimeEpoch; | ||
var serverDate; | ||
var liveSupport; | ||
@@ -72,3 +76,3 @@ var playerComponent; | ||
function deviceTimeToDate (time) { | ||
if (liveWindowStart) { | ||
if (windowStartTime) { | ||
return new Date(convertVideoTimeSecondsToEpochMs(time)); | ||
@@ -81,3 +85,3 @@ } else { | ||
function convertVideoTimeSecondsToEpochMs (seconds) { | ||
return liveWindowStart ? liveWindowStart + (seconds * 1000) : undefined; | ||
return windowStartTime ? windowStartTime + (seconds * 1000) : undefined; | ||
} | ||
@@ -88,5 +92,30 @@ | ||
Chronicle.init(); | ||
if (newWindowType !== WindowTypes.STATIC) { | ||
if (bigscreenPlayerData.time) { | ||
windowStartTime = bigscreenPlayerData.time.windowStartTime; | ||
windowEndTime = bigscreenPlayerData.time.windowEndTime; | ||
serverDate = bigscreenPlayerData.serverDate; | ||
} else if (bigscreenPlayerData.media.manifest) { | ||
var manifestParser = new ManifestParser(bigscreenPlayerData.media.manifest, bigscreenPlayerData.media.manifestType, bigscreenPlayerData.serverDate); | ||
var liveWindowData = manifestParser.parse(); | ||
windowStartTime = liveWindowData.windowStartTime; | ||
windowEndTime = liveWindowData.windowEndTime; | ||
serverDate = bigscreenPlayerData.serverDate; | ||
bigscreenPlayerData.time = {}; | ||
bigscreenPlayerData.time.windowStartTime = windowStartTime; | ||
bigscreenPlayerData.time.windowEndTime = windowEndTime; | ||
bigscreenPlayerData.time.correction = liveWindowData.timeCorrection; | ||
} | ||
initialPlaybackTimeEpoch = bigscreenPlayerData.initialPlaybackTime; | ||
// overwrite initialPlaybackTime with video time (it comes in as epoch time for a sliding/growing window) | ||
bigscreenPlayerData.initialPlaybackTime = SlidingWindowUtils.convertToSeekableVideoTime(bigscreenPlayerData.initialPlaybackTime, windowStartTime); | ||
} | ||
mediaKind = bigscreenPlayerData.media.kind; | ||
liveWindowStart = bigscreenPlayerData.time && bigscreenPlayerData.time.windowStartTime; | ||
liveWindowEnd = bigscreenPlayerData.time && bigscreenPlayerData.time.windowEndTime; | ||
liveSupport = newLiveSupport; | ||
@@ -118,4 +147,4 @@ windowType = newWindowType; | ||
mediaKind = undefined; | ||
liveWindowStart = undefined; | ||
liveWindowEnd = undefined; | ||
windowStartTime = undefined; | ||
windowEndTime = undefined; | ||
liveSupport = undefined; | ||
@@ -172,2 +201,13 @@ pauseTrigger = undefined; | ||
}, | ||
getLiveWindowData: function () { | ||
if (windowType === WindowTypes.STATIC) { | ||
return {}; | ||
} | ||
return { | ||
windowStartTime: windowStartTime, | ||
windowEndTime: windowEndTime, | ||
initialPlaybackTime: initialPlaybackTimeEpoch, | ||
serverDate: serverDate | ||
}; | ||
}, | ||
getDuration: function () { | ||
@@ -204,6 +244,6 @@ return playerComponent && playerComponent.getDuration(); | ||
canSeek: function () { | ||
return windowType === WindowTypes.STATIC || DynamicWindowUtils.canSeek(liveWindowStart, liveWindowEnd, liveSupport, this.getSeekableRange()); | ||
return windowType === WindowTypes.STATIC || DynamicWindowUtils.canSeek(windowStartTime, windowEndTime, liveSupport, this.getSeekableRange()); | ||
}, | ||
canPause: function () { | ||
return windowType === WindowTypes.STATIC || DynamicWindowUtils.canPause(liveWindowStart, liveWindowEnd, liveSupport); | ||
return windowType === WindowTypes.STATIC || DynamicWindowUtils.canPause(windowStartTime, windowEndTime, liveSupport); | ||
}, | ||
@@ -231,2 +271,5 @@ mock: function (opts) { | ||
}, | ||
convertEpochMsToVideoTimeSeconds: function (epochTime) { | ||
return windowStartTime ? Math.floor((epochTime - windowStartTime) / 1000) : undefined; | ||
}, | ||
convertVideoTimeSecondsToEpochMs: convertVideoTimeSecondsToEpochMs | ||
@@ -233,0 +276,0 @@ }; |
@@ -46,2 +46,4 @@ define('bigscreenplayer/mockbigscreenplayer', | ||
var liveWindowData; | ||
function startProgress (progressCause) { | ||
@@ -275,2 +277,13 @@ setTimeout(function () { | ||
Plugins.unregisterPlugin(plugin); | ||
}, | ||
getLiveWindowData: function () { | ||
if (windowType === WindowTypes.STATIC) { | ||
return {}; | ||
} | ||
return { | ||
windowStartTime: liveWindowData.windowStartTime, | ||
windowEndTime: liveWindowData.windowEndTime, | ||
initialPlaybackTime: liveWindowData.initialPlaybackTime, | ||
serverDate: liveWindowData.serverDate | ||
}; | ||
} | ||
@@ -384,2 +397,5 @@ }; | ||
initialBuffering = value; | ||
}, | ||
setLiveWindowData: function (newLiveWindowData) { | ||
liveWindowData = newLiveWindowData; | ||
} | ||
@@ -386,0 +402,0 @@ }; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
6763476
73
61057
16