bigscreen-player
Advanced tools
Comparing version 2.0.0 to 2.1.0
{ | ||
"name": "bigscreen-player", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "Simplified media playback for bigscreen devices.", | ||
@@ -5,0 +5,0 @@ "main": "script/bigscreenplayer.js", |
@@ -37,2 +37,4 @@ require( | ||
var cdnArray = []; | ||
var device = { | ||
@@ -75,2 +77,4 @@ getConfig: function () { | ||
cdnArray.push({url: 'testcdn1/test/', cdn: 'cdn1'}); | ||
var config = options.config || device.getConfig(); | ||
@@ -114,5 +118,5 @@ | ||
legacyAdaptor.load('src', 'video/mp4', 0); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 0); | ||
expect(mediaPlayer.initialiseMedia).toHaveBeenCalledWith('video', 'src', 'video/mp4', videoContainer, jasmine.any(Object)); | ||
expect(mediaPlayer.initialiseMedia).toHaveBeenCalledWith('video', cdnArray[0].url, 'video/mp4', videoContainer, jasmine.any(Object)); | ||
}); | ||
@@ -123,3 +127,3 @@ | ||
legacyAdaptor.load('src', 'video/mp4', 50); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 50); | ||
@@ -132,3 +136,3 @@ expect(mediaPlayer.beginPlaybackFrom).toHaveBeenCalledWith(60); | ||
legacyAdaptor.load('src', 'video/mp4', undefined); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', undefined); | ||
@@ -141,3 +145,3 @@ expect(mediaPlayer.beginPlayback).toHaveBeenCalledWith(); | ||
legacyAdaptor.load('src', 'video/mp4', 50); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 50); | ||
@@ -150,3 +154,3 @@ expect(mediaPlayer.beginPlaybackFrom).toHaveBeenCalledWith(50); | ||
legacyAdaptor.load('src', 'video/mp4', undefined); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', undefined); | ||
@@ -167,3 +171,3 @@ expect(mediaPlayer.beginPlaybackFrom).toHaveBeenCalledWith(0); | ||
legacyAdaptor.load('src', 'video/mp4', undefined); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', undefined); | ||
@@ -230,3 +234,3 @@ var properties = mediaPlayer.initialiseMedia.calls.mostRecent().args[4]; | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -247,3 +251,3 @@ legacyAdaptor.setCurrentTime(10); | ||
legacyAdaptor.load('src', 'video/mp4', undefined); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', undefined); | ||
@@ -486,3 +490,3 @@ expect(legacyAdaptor.isPaused()).toEqual(false); | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -551,3 +555,3 @@ eventCallbacks({type: MediaPlayerEvent.PAUSED}); | ||
legacyAdaptor.load('src', 'video/mp4', 10); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 10); | ||
@@ -562,3 +566,3 @@ eventCallbacks({type: MediaPlayerEvent.SEEK_ATTEMPTED}); | ||
legacyAdaptor.load('src', 'video/mp4', 0); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 0); | ||
@@ -573,3 +577,3 @@ eventCallbacks({type: MediaPlayerEvent.SEEK_ATTEMPTED}); | ||
legacyAdaptor.load('src', 'video/mp4'); | ||
legacyAdaptor.load(cdnArray, 'video/mp4'); | ||
@@ -610,3 +614,3 @@ eventCallbacks({type: MediaPlayerEvent.SEEK_ATTEMPTED}); | ||
legacyAdaptor.load('src', 'video/mp4', 0); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 0); | ||
@@ -625,3 +629,3 @@ eventCallbacks({type: MediaPlayerEvent.SEEK_ATTEMPTED}); | ||
legacyAdaptor.load('src', 'video/mp4', 0); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', 0); | ||
@@ -641,3 +645,3 @@ eventCallbacks({type: MediaPlayerEvent.SEEK_ATTEMPTED}); | ||
// set up the values handleErrorOnExitingSeek && exitingSeek so they are truthy then fire an error event so we restart. | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -654,3 +658,3 @@ legacyAdaptor.setCurrentTime(10); | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -661,3 +665,3 @@ legacyAdaptor.setCurrentTime(10); | ||
expect(mediaPlayer.initialiseMedia).toHaveBeenCalledWith('video', 'src', 'application/dash+xml', videoContainer, jasmine.any(Object)); | ||
expect(mediaPlayer.initialiseMedia).toHaveBeenCalledWith('video', cdnArray[0].url, 'application/dash+xml', videoContainer, jasmine.any(Object)); | ||
}); | ||
@@ -668,3 +672,3 @@ | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -681,3 +685,3 @@ legacyAdaptor.setCurrentTime(10); | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -696,3 +700,3 @@ legacyAdaptor.setCurrentTime(10); | ||
legacyAdaptor.load('src', 'application/dash+xml', undefined); | ||
legacyAdaptor.load(cdnArray, 'application/dash+xml', undefined); | ||
@@ -719,3 +723,3 @@ eventCallbacks({type: MediaPlayerEvent.PAUSED}); | ||
legacyAdaptor.load('src', 'video/mp4', undefined); | ||
legacyAdaptor.load(cdnArray, 'video/mp4', undefined); | ||
@@ -722,0 +726,0 @@ eventCallbacks({type: MediaPlayerEvent.PAUSED}); |
@@ -22,2 +22,3 @@ require( | ||
var mockPluginsInterface; | ||
var cdnArray = []; | ||
@@ -31,3 +32,5 @@ var mockAudioElement = document.createElement('audio'); | ||
QUALITY_CHANGE_RENDERED: 'qualityChangeRendered', | ||
METRIC_ADDED: 'metricAdded' | ||
CDN_FAILOVER: 'baseUrlSelected', | ||
METRIC_ADDED: 'metricAdded', | ||
METRIC_CHANGED: 'metricChanged' | ||
}; | ||
@@ -37,6 +40,15 @@ | ||
mockDashMediaPlayer = jasmine.createSpyObj('mockDashMediaPlayer', ['create']); | ||
mockPluginsInterface = jasmine.createSpyObj('interface', ['onErrorCleared', 'onBuffering', 'onBufferingCleared', 'onError', 'onFatalError', 'onErrorHandled', 'onPlayerInfoUpdated']); | ||
mockPlugins = { | ||
interface: mockPluginsInterface | ||
}; | ||
beforeEach(function (done) { | ||
cdnArray = []; | ||
cdnArray.push({url: 'testcdn1/test/', cdn: 'cdn1'}); | ||
injector.mock({ | ||
'dashjs': mockDashjs | ||
'dashjs': mockDashjs, | ||
'bigscreenplayer/plugins': mockPlugins | ||
}); | ||
@@ -71,4 +83,6 @@ | ||
mseStrategy = MSEStrategy(defaultWindowType, defaultMediaKind, timeModel, playbackElement); | ||
var mockCdnDebugOutput = jasmine.createSpyObj('mockCdnDebugOutput', ['update', 'tearDown']); | ||
mseStrategy = MSEStrategy(defaultWindowType, defaultMediaKind, timeModel, playbackElement, {}, false, mockCdnDebugOutput); | ||
mockDashDebug = jasmine.createSpyObj('mockDashDebug', ['setLogToBrowserConsole']); | ||
@@ -129,2 +143,3 @@ | ||
document.body.removeChild(playbackElement); | ||
mockPluginsInterface.onErrorHandled.calls.reset(); | ||
}); | ||
@@ -152,3 +167,3 @@ | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -164,3 +179,3 @@ expect(playbackElement.firstChild).toBe(mockVideoElement); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -173,6 +188,6 @@ expect(playbackElement.firstChild).toBe(mockAudioElement); | ||
setUpMSE(); | ||
mseStrategy.load('src', null, undefined); | ||
mseStrategy.load(cdnArray, null, undefined); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url, jasmine.any(Function)); | ||
}); | ||
@@ -183,6 +198,6 @@ | ||
setUpMSE(); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url, jasmine.any(Function)); | ||
}); | ||
@@ -192,6 +207,6 @@ | ||
setUpMSE(); | ||
mseStrategy.load('src', null, 15); | ||
mseStrategy.load(cdnArray, null, 15); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#t=15', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=15', jasmine.any(Function)); | ||
}); | ||
@@ -206,6 +221,6 @@ }); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url, jasmine.any(Function)); | ||
}); | ||
@@ -218,6 +233,6 @@ | ||
mseStrategy.load('src', null, 0.1); | ||
mseStrategy.load(cdnArray, null, 0.1); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#r=0', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#r=0', jasmine.any(Function)); | ||
}); | ||
@@ -230,6 +245,6 @@ | ||
mseStrategy.load('src', null, 100); | ||
mseStrategy.load(cdnArray, null, 100); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#r=100', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#r=100', jasmine.any(Function)); | ||
}); | ||
@@ -244,6 +259,6 @@ }); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#t=101', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=101', jasmine.any(Function)); | ||
}); | ||
@@ -256,6 +271,6 @@ | ||
mseStrategy.load('src', null, 0.1); | ||
mseStrategy.load(cdnArray, null, 0.1); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#t=101', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=101', jasmine.any(Function)); | ||
}); | ||
@@ -268,6 +283,6 @@ | ||
mseStrategy.load('src', null, 60); | ||
mseStrategy.load(cdnArray, null, 60); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#t=160', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=160', jasmine.any(Function)); | ||
}); | ||
@@ -278,3 +293,3 @@ }); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -301,12 +316,16 @@ expect(mockVideoElement.addEventListener).toHaveBeenCalledWith('timeupdate', jasmine.any(Function)); | ||
cdnArray.push({url: 'testcdn2/test/', cdn: 'cdn2'}); | ||
mockDashInstance.getSource.and.returnValue('src'); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url, jasmine.any(Function)); | ||
mseStrategy.load('src2', null, 0); | ||
cdnArray.shift(); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src2', jasmine.any(Function)); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url, jasmine.any(Function)); | ||
}); | ||
@@ -317,16 +336,23 @@ | ||
cdnArray.push({url: 'testcdn2/test/', cdn: 'cdn2'}); | ||
cdnArray.push({url: 'testcdn3/test/', cdn: 'cdn3'}); | ||
mockDashInstance.getSource.and.returnValue('src'); | ||
mseStrategy.load('src', null, 45); | ||
mseStrategy.load(cdnArray, null, 45); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#t=45', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=45', jasmine.any(Function)); | ||
mseStrategy.load('src2', null, 0); | ||
cdnArray.shift(); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src2#t=45', jasmine.any(Function)); | ||
mseStrategy.load(cdnArray, null, 0); | ||
mseStrategy.load('src3', null, 0); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=45', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src3#t=45', jasmine.any(Function)); | ||
cdnArray.shift(); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=45', jasmine.any(Function)); | ||
}); | ||
@@ -337,15 +363,45 @@ | ||
cdnArray.push({url: 'testcdn2/test/', cdn: 'cdn2'}); | ||
mockDashInstance.getSource.and.returnValue('src'); | ||
mseStrategy.load('src', null, 45); | ||
mseStrategy.load(cdnArray, null, 45); | ||
expect(mockDashInstance.initialize).toHaveBeenCalledWith(mockVideoElement, null, true); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src#t=45', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=45', jasmine.any(Function)); | ||
cdnArray.shift(); | ||
mockVideoElement.currentTime = 86; | ||
eventHandlers.timeupdate(); | ||
mseStrategy.load('src2', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith('src2#t=86', jasmine.any(Function)); | ||
expect(mockDashInstance.retrieveManifest).toHaveBeenCalledWith(cdnArray[0].url + '#t=86', jasmine.any(Function)); | ||
}); | ||
it('should fire download error event when in growing window', function () { | ||
setUpMSE(); | ||
mseStrategy.load(cdnArray, WindowTypes.GROWING, 3); | ||
eventHandlers.error({ | ||
errorMessage: 'Boom' | ||
}); | ||
expect(mockPluginsInterface.onErrorHandled).not.toHaveBeenCalled(); | ||
}); | ||
it('should call plugin handler on dash baseUrl changed event', function () { | ||
setUpMSE(); | ||
mseStrategy.load(cdnArray, WindowTypes.STATIC, 3); | ||
eventHandlers.baseUrlSelected({ | ||
baseUrl: { | ||
url: cdnArray[0].cdn | ||
} | ||
}); | ||
expect(mockPluginsInterface.onErrorHandled).toHaveBeenCalled(); | ||
}); | ||
}); | ||
@@ -356,3 +412,3 @@ | ||
setUpMSE(); | ||
mseStrategy.load('src', null, 45); | ||
mseStrategy.load(cdnArray, null, 45); | ||
@@ -368,3 +424,3 @@ expect(mseStrategy.getSeekableRange()).toEqual({start: 0, end: 101}); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -385,3 +441,3 @@ expect(mseStrategy.getCurrentTime()).toBe(10); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -401,3 +457,3 @@ expect(mseStrategy.getDuration()).toBe(101); | ||
setUpMSE(); | ||
mseStrategy.load('src', null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -411,3 +467,3 @@ mseStrategy.tearDown(); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -433,3 +489,3 @@ mseStrategy.tearDown(); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -447,3 +503,3 @@ expect(playbackElement.childElementCount).toBe(1); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -455,3 +511,3 @@ expect(mseStrategy.isEnded()).toBe(false); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -465,3 +521,3 @@ eventCallbacks('ended'); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -475,3 +531,3 @@ eventCallbacks('playing'); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -485,3 +541,3 @@ eventCallbacks('waiting'); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -501,3 +557,3 @@ eventCallbacks('ended'); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -511,3 +567,3 @@ mockDashInstance.isPaused.and.returnValue(false); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -523,3 +579,3 @@ mockDashInstance.isPaused.and.returnValue(true); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -535,3 +591,3 @@ mseStrategy.pause(); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -547,3 +603,3 @@ mseStrategy.play(); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -557,3 +613,3 @@ mseStrategy.setCurrentTime(12); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -567,3 +623,3 @@ mseStrategy.setCurrentTime(-0.1); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -577,3 +633,3 @@ mseStrategy.setCurrentTime(101); | ||
setUpMSE(0, WindowTypes.GROWING, MediaKinds.VIDEO); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -589,3 +645,3 @@ mseStrategy.setCurrentTime(102); | ||
setUpMSE(0, WindowTypes.SLIDING, MediaKinds.VIDEO); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
}); | ||
@@ -621,10 +677,2 @@ | ||
mockPluginsInterface = jasmine.createSpyObj('interface', ['onErrorCleared', 'onBuffering', 'onBufferingCleared', 'onError', 'onFatalError', 'onErrorHandled', 'onPlayerInfoUpdated']); | ||
mockPlugins = { | ||
interface: mockPluginsInterface | ||
}; | ||
injector.mock({'bigscreenplayer/plugins': mockPlugins}); | ||
beforeEach(function () { | ||
@@ -637,3 +685,3 @@ mockPluginsInterface.onPlayerInfoUpdated.calls.reset(); | ||
mockDashInstance.getBitrateInfoListFor.and.returnValue([{bitrate: 1000}, {bitrate: 2048}, {bitrate: 3000}]); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -658,3 +706,3 @@ dashEventCallback(dashjsMediaPlayerEvents.QUALITY_CHANGE_RENDERED, mockEvent); | ||
mockDashInstance.getBitrateInfoListFor.and.returnValue([{bitrate: 1000}, {bitrate: 2048}, {bitrate: 3000}]); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -673,3 +721,3 @@ dashEventCallback(dashjsMediaPlayerEvents.QUALITY_CHANGE_RENDERED, mockEvent); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -698,3 +746,3 @@ mockDashInstance.getMetricsFor.and.returnValue(true); | ||
setUpMSE(); | ||
mseStrategy.load(null, null, 0); | ||
mseStrategy.load(cdnArray, null, 0); | ||
@@ -701,0 +749,0 @@ mockDashInstance.getMetricsFor.and.returnValue(true); |
@@ -860,3 +860,2 @@ require( | ||
it('should failover after buffering for 30 seconds on initial playback', function () { | ||
var secondCdn = 'b'; | ||
var currentTime = 10; | ||
@@ -880,7 +879,6 @@ var type = 'application/dash+xml'; | ||
expect(mockStrategy.load).toHaveBeenCalledWith(secondCdn, type, currentTime); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(corePlaybackData.media.urls, type, currentTime); | ||
}); | ||
it('should failover after buffering for 20 seconds on normal playback', function () { | ||
var secondCdn = 'b'; | ||
var currentTime = 10; | ||
@@ -910,3 +908,3 @@ var type = 'application/dash+xml'; | ||
expect(mockStrategy.load).toHaveBeenCalledWith(secondCdn, type, currentTime); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(corePlaybackData.media.urls, type, currentTime); | ||
@@ -918,3 +916,2 @@ expect(corePlaybackData.media.urls.length).toBe(2); | ||
it('should failover after 5 seconds if we have not cleared an error from the device', function () { | ||
var secondCdn = 'b'; | ||
var currentTime = 10; | ||
@@ -933,2 +930,3 @@ var type = 'application/dash+xml'; | ||
expect(mockStrategy.load).toHaveBeenCalledTimes(1); | ||
expect(corePlaybackData.media.urls.length).toBe(3); | ||
@@ -939,3 +937,5 @@ jasmine.clock().tick(1); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(secondCdn, type, currentTime); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(corePlaybackData.media.urls, type, currentTime); | ||
expect(corePlaybackData.media.urls.length).toBe(2); | ||
}); | ||
@@ -1010,3 +1010,2 @@ | ||
it('should failover on a seekable device when playing hls webcasts', function () { | ||
var secondCdn = 'b'; | ||
var currentTime = 10; | ||
@@ -1036,3 +1035,3 @@ var type = 'application/vnd.apple.mpegurl'; | ||
expect(mockStrategy.load).toHaveBeenCalledWith(secondCdn, type, currentTime); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(corePlaybackData.media.urls, type, currentTime); | ||
@@ -1044,3 +1043,2 @@ expect(corePlaybackData.media.urls.length).toBe(2); | ||
it('should failover on a playable device when playing hls webcasts', function () { | ||
var secondCdn = 'b'; | ||
var currentTime = 10; | ||
@@ -1071,3 +1069,3 @@ var type = 'application/vnd.apple.mpegurl'; | ||
expect(mockStrategy.load).toHaveBeenCalledWith(secondCdn, type, currentTime); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(corePlaybackData.media.urls, type, currentTime); | ||
@@ -1079,3 +1077,2 @@ expect(corePlaybackData.media.urls.length).toBe(2); | ||
it('should failover after buffering for 20 seconds on live dash playback', function () { | ||
var secondCdn = 'b'; | ||
var currentTime = 94; | ||
@@ -1099,2 +1096,3 @@ var type = 'application/dash+xml'; | ||
expect(mockStrategy.load).toHaveBeenCalledTimes(1); | ||
expect(corePlaybackData.media.urls.length).toBe(3); | ||
@@ -1105,3 +1103,4 @@ jasmine.clock().tick(1); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(secondCdn, type, currentTime); | ||
expect(mockStrategy.load).toHaveBeenCalledWith(corePlaybackData.media.urls, type, currentTime); | ||
expect(corePlaybackData.media.urls.length).toBe(2); | ||
}); | ||
@@ -1108,0 +1107,0 @@ |
@@ -9,10 +9,10 @@ define('bigscreenplayer/playbackstrategy/hybridstrategy', | ||
function (Native, MSE, StrategyPicker, LiveSupport) { | ||
var HybridStrategy = function (windowType, mediaKind, timeCorrection, videoElement, isUHD, device) { | ||
var HybridStrategy = function (windowType, mediaKind, timeCorrection, videoElement, isUHD, device, cdnDebugOutput) { | ||
var strategy = StrategyPicker(windowType, isUHD); | ||
if (strategy === 'mseStrategy') { | ||
return MSE(windowType, mediaKind, timeCorrection, videoElement, isUHD); | ||
return MSE(windowType, mediaKind, timeCorrection, videoElement, isUHD, device, cdnDebugOutput); | ||
} | ||
return Native(windowType, mediaKind, timeCorrection, videoElement, isUHD, device); | ||
return Native(windowType, mediaKind, timeCorrection, videoElement, isUHD, device, cdnDebugOutput); | ||
}; | ||
@@ -19,0 +19,0 @@ |
@@ -244,3 +244,4 @@ define('bigscreenplayer/playbackstrategy/legacyplayeradapter', | ||
}, | ||
load: function (src, mimeType, startTime) { | ||
load: function (cdns, mimeType, startTime) { | ||
var source = cdns[0].url; | ||
setupExitSeekWorkarounds(mimeType); | ||
@@ -252,3 +253,3 @@ isPaused = false; | ||
mediaPlayer.initialiseMedia('video', src, mimeType, playbackElement, setSourceOpts); | ||
mediaPlayer.initialiseMedia('video', source, mimeType, playbackElement, setSourceOpts); | ||
if (mediaPlayer.beginPlaybackFrom && !isPlaybackFromLivePoint) { | ||
@@ -255,0 +256,0 @@ currentTime = startTime; |
@@ -8,3 +8,6 @@ define('bigscreenplayer/playbackstrategy/msestrategy', | ||
'bigscreenplayer/plugins', | ||
'bigscreenplayer/plugindata', | ||
'bigscreenplayer/pluginenums', | ||
'bigscreenplayer/manifest/manifestfilter', | ||
'bigscreenplayer/utils/playbackutils', | ||
'bigscreenplayer/models/livesupport', | ||
@@ -15,13 +18,14 @@ | ||
], | ||
function (MediaState, WindowTypes, DebugTool, MediaKinds, Plugins, ManifestFilter, LiveSupport) { | ||
var MSEStrategy = function (windowType, mediaKind, timeData, playbackElement) { | ||
function (MediaState, WindowTypes, DebugTool, MediaKinds, Plugins, PluginData, PluginEnums, ManifestFilter, PlaybackUtils, LiveSupport) { | ||
var MSEStrategy = function (windowType, mediaKind, timeData, playbackElement, isUHD, device, cdnDebugOutput) { | ||
var mediaPlayer; | ||
var mediaElement; | ||
var eventCallback; | ||
var errorCallback; | ||
var timeUpdateCallback; | ||
var timeCorrection = timeData && timeData.correction || 0; | ||
var failoverTime; | ||
var isEnded = false; | ||
var mediaElement; | ||
@@ -32,2 +36,5 @@ var bitrateInfoList; | ||
var mediaSources; | ||
var cdns; | ||
var playerMetadata = { | ||
@@ -41,4 +48,9 @@ playbackBitrate: undefined, | ||
MANIFEST_LOADED: 'manifestLoaded', | ||
DOWNLOAD_MANIFEST_ERROR_CODE: 25, | ||
DOWNLOAD_SIDX_ERROR_CODE: 26, | ||
DOWNLOAD_CONTENT_ERROR_CODE: 27, | ||
DOWNLOAD_ERROR_MESSAGE: 'download', | ||
MANIFEST_VALIDITY_CHANGED: 'manifestValidityChanged', | ||
QUALITY_CHANGE_RENDERED: 'qualityChangeRendered', | ||
CDN_FAILOVER: 'baseUrlSelected', | ||
METRIC_ADDED: 'metricAdded', | ||
@@ -95,4 +107,16 @@ METRIC_CHANGED: 'metricChanged' | ||
DebugTool.info('MSE Error: ' + event.error.message); | ||
// Don't raise an error on fragment download error | ||
if (event.error.code === DashJSEvents.DOWNLOAD_SIDX_ERROR_CODE || | ||
event.error.code === DashJSEvents.DOWNLOAD_CONTENT_ERROR_CODE || | ||
event.error.code === DashJSEvents.DOWNLOAD_MANIFEST_ERROR_CODE) { | ||
return; | ||
} | ||
} else { | ||
DebugTool.info('MSE Error: ' + event.error); | ||
// Don't raise an error on fragment download error unless we want to do a standard failover for growing windows | ||
if (event.error === DashJSEvents.DOWNLOAD_ERROR_MESSAGE && windowType !== WindowTypes.GROWING) { | ||
return; | ||
} | ||
} | ||
@@ -129,2 +153,51 @@ } | ||
function createPlaybackProperties () { | ||
return { | ||
seekable_range: getSeekableRange().start + ' to ' + getSeekableRange().end, | ||
current_time: getCurrentTime(), | ||
duration: getDuration() | ||
}; | ||
} | ||
function propagateCdnFailover (event, cdn) { | ||
// Initial playback | ||
if (cdn === mediaSources[0].cdn) return; | ||
var errorProperties = PlaybackUtils.merge(createPlaybackProperties(), event.errorProperties); | ||
var evt = new PluginData({ | ||
status: PluginEnums.STATUS.FAILOVER, | ||
stateType: PluginEnums.TYPE.ERROR, | ||
properties: errorProperties, | ||
isBufferingTimeoutError: false, | ||
cdn: cdn | ||
}); | ||
// urls -> sources -> mediaSources (shift the cdns for correct behaviour with buffering timeout failover) | ||
// TODO: Remove this horrible mutation when failover is pushed down per strategy. | ||
mediaSources.shift(); | ||
Plugins.interface.onErrorHandled(evt); | ||
cdnDebugOutput.update(); | ||
} | ||
function onCdnFailover (event) { | ||
if (windowType === WindowTypes.GROWING) return; | ||
var cdn; | ||
if (event.baseUrl.url) { | ||
cdns.forEach(function (element) { | ||
if (event.baseUrl.serviceLocation === element) { | ||
cdn = element; | ||
} | ||
}); | ||
} | ||
var pluginEvent = { | ||
errorProperties: { | ||
error_mssg: 'download' | ||
} | ||
}; | ||
propagateCdnFailover(pluginEvent, cdn); | ||
} | ||
function onMetricAdded (event) { | ||
@@ -187,3 +260,3 @@ if (event.mediaType === 'video') { | ||
function setUpMediaPlayer (src) { | ||
function setUpMediaPlayer (sources, playbackTime) { | ||
mediaPlayer = dashjs.MediaPlayer().create(); | ||
@@ -199,8 +272,53 @@ mediaPlayer.getDebug().setLogToBrowserConsole(false); | ||
mediaPlayer.initialize(mediaElement, null, true); | ||
modifySource(src); | ||
modifySource(sources, playbackTime); | ||
} | ||
function modifySource (src) { | ||
mediaPlayer.retrieveManifest(src, function (manifest) { | ||
/** | ||
* | ||
* Edge case for growing window - only use one source at a time, do a legacy failover as we don't refresh the manifest. | ||
* | ||
* @param {*} sources | ||
* @param {*} playbackTime | ||
*/ | ||
function modifySource (sources, playbackTime) { | ||
mediaSources = sources; | ||
var regexp = /.*\//; | ||
var initialSource = calculateSourceAnchor(sources[0].url, playbackTime); | ||
cdns = sources.map(function (source) { | ||
return source.cdn; | ||
}); | ||
if (windowType !== WindowTypes.GROWING) { | ||
var baseUrls = sources.map(function (source, priority) { | ||
var sourceUrl = regexp.exec(source.url)[0]; | ||
return { | ||
__text: sourceUrl + 'dash/', | ||
'dvb:priority': priority, | ||
serviceLocation: source.cdn | ||
}; | ||
}); | ||
} | ||
mediaPlayer.retrieveManifest(initialSource, function (manifest) { | ||
if (manifest === null) { | ||
var event = { | ||
errorProperties: { | ||
error_mssg: 'manifestDownloadError' | ||
} | ||
}; | ||
DebugTool.info('MSE Error: manifestDownloadError'); | ||
publishError(event); | ||
return; | ||
} | ||
var filteredManifest = ManifestFilter.filter(manifest, window.bigscreenPlayer.representationOptions || {}); | ||
if (windowType !== WindowTypes.GROWING) { | ||
filteredManifest.BaseURL_asArray = baseUrls; | ||
delete filteredManifest.Period.BaseURL; | ||
delete filteredManifest.Period.BaseURL_asArray; | ||
} | ||
mediaPlayer.attachSource(filteredManifest); | ||
@@ -223,2 +341,3 @@ }); | ||
mediaPlayer.on(DashJSEvents.QUALITY_CHANGE_RENDERED, onQualityChangeRendered); | ||
mediaPlayer.on(DashJSEvents.CDN_FAILOVER, onCdnFailover); | ||
mediaPlayer.on(DashJSEvents.METRIC_ADDED, onMetricAdded); | ||
@@ -259,2 +378,26 @@ } | ||
function getSeekableRange () { | ||
if (mediaPlayer && mediaPlayer.isReady() && windowType !== WindowTypes.STATIC) { | ||
var dvrInfo = mediaPlayer.getDashMetrics().getCurrentDVRInfo(mediaPlayer.getMetricsFor(mediaKind)); | ||
if (dvrInfo) { | ||
return { | ||
start: dvrInfo.range.start - timeCorrection, | ||
end: dvrInfo.range.end - timeCorrection | ||
}; | ||
} | ||
} | ||
return { | ||
start: 0, | ||
end: getDuration() | ||
}; | ||
} | ||
function getDuration () { | ||
return (mediaPlayer && mediaPlayer.isReady()) ? mediaPlayer.duration() : 0; | ||
} | ||
function getCurrentTime () { | ||
return (mediaElement) ? mediaElement.currentTime - timeCorrection : 0; | ||
} | ||
return { | ||
@@ -280,33 +423,17 @@ transitions: { | ||
}, | ||
load: function (src, mimeType, playbackTime) { | ||
load: function (sources, mimeType, playbackTime) { | ||
if (sources && sources.length === 0) return; | ||
if (!mediaPlayer) { | ||
failoverTime = playbackTime; | ||
setUpMediaElement(playbackElement); | ||
setUpMediaPlayer(calculateSourceAnchor(src, playbackTime)); | ||
setUpMediaPlayer(sources, playbackTime); | ||
setUpMediaListeners(); | ||
} else { | ||
modifySource(calculateSourceAnchor(src, failoverTime)); | ||
modifySource(sources, failoverTime); | ||
} | ||
}, | ||
getSeekableRange: function () { | ||
if (mediaPlayer && mediaPlayer.isReady() && windowType !== WindowTypes.STATIC) { | ||
var dvrInfo = mediaPlayer.getDashMetrics().getCurrentDVRInfo(mediaPlayer.getMetricsFor(mediaKind)); | ||
if (dvrInfo) { | ||
return { | ||
start: dvrInfo.range.start - timeCorrection, | ||
end: dvrInfo.range.end - timeCorrection | ||
}; | ||
} | ||
} | ||
return { | ||
start: 0, | ||
end: this.getDuration() | ||
}; | ||
}, | ||
getCurrentTime: function () { | ||
return (mediaElement) ? mediaElement.currentTime - timeCorrection : 0; | ||
}, | ||
getDuration: function () { | ||
return (mediaPlayer && mediaPlayer.isReady()) ? mediaPlayer.duration() : 0; | ||
}, | ||
getSeekableRange: getSeekableRange, | ||
getCurrentTime: getCurrentTime, | ||
getDuration: getDuration, | ||
tearDown: function () { | ||
@@ -328,2 +455,3 @@ mediaPlayer.reset(); | ||
mediaPlayer.off(DashJSEvents.METRIC_ADDED, onMetricAdded); | ||
mediaPlayer.off(DashJSEvents.CDN_FAILOVER, onCdnFailover); | ||
@@ -337,6 +465,10 @@ mediaElement.parentElement.removeChild(mediaElement); | ||
timeUpdateCallback = undefined; | ||
timeCorrection = undefined; | ||
failoverTime = undefined; | ||
isEnded = undefined; | ||
failoverTime = undefined; | ||
timeCorrection = undefined; | ||
windowType = undefined; | ||
bitrateInfoList = undefined; | ||
mediaMetrics = undefined; | ||
dashMetrics = undefined; | ||
cdns = undefined; | ||
mediaSources = undefined; | ||
}, | ||
@@ -362,3 +494,3 @@ reset: function () { | ||
var seekToTime = getClampedTime(time, this.getSeekableRange()); | ||
var seekToTime = getClampedTime(time, getSeekableRange()); | ||
@@ -365,0 +497,0 @@ if (windowType === WindowTypes.SLIDING) { |
@@ -12,6 +12,6 @@ define( | ||
'bigscreenplayer/plugins', | ||
'bigscreenplayer/debugger/debugtool', | ||
'bigscreenplayer/debugger/cdndebugoutput', | ||
'bigscreenplayer/models/transferformats' | ||
], | ||
function (MediaState, CaptionsContainer, PlaybackStrategy, WindowTypes, PlaybackUtils, LiveSupport, PluginData, PluginEnums, Plugins, DebugTool, TransferFormats) { | ||
function (MediaState, CaptionsContainer, PlaybackStrategy, WindowTypes, PlaybackUtils, LiveSupport, PluginData, PluginEnums, Plugins, CdnDebugOutput, TransferFormats) { | ||
'use strict'; | ||
@@ -32,2 +32,3 @@ | ||
var fatalError; | ||
var cdnDebugOutput = new CdnDebugOutput(bigscreenPlayerData.media.urls); | ||
var transferFormat = bigscreenPlayerData.media.transferFormat; | ||
@@ -41,3 +42,4 @@ | ||
bigscreenPlayerData.media.isUHD, | ||
device | ||
device, | ||
cdnDebugOutput | ||
); | ||
@@ -186,3 +188,3 @@ | ||
var playbackErrorProperties = createPlaybackErrorProperties(event); | ||
raiseError(playbackErrorProperties); | ||
raiseError(playbackErrorProperties, false); | ||
} | ||
@@ -243,11 +245,4 @@ | ||
Plugins.interface.onErrorHandled(evt); | ||
var availableCdns = mediaMetaData.urls.map(function (media) { | ||
return media.cdn; | ||
}); | ||
DebugTool.keyValue({key: 'available cdns', value: availableCdns}); | ||
DebugTool.keyValue({key: 'current cdn', value: mediaMetaData.urls[0].cdn}); | ||
DebugTool.keyValue({key: 'url', value: mediaMetaData.urls[0].url}); | ||
loadMedia(mediaMetaData.urls[0].url, mediaMetaData.type, getCurrentTime(), thenPause); | ||
cdnDebugOutput.update(); | ||
loadMedia(mediaMetaData.urls, mediaMetaData.type, getCurrentTime(), thenPause); | ||
} | ||
@@ -344,3 +339,3 @@ | ||
mediaMetaData = media; | ||
loadMedia(media.urls[0].url, media.type, startTime); | ||
loadMedia(media.urls, media.type, startTime); | ||
@@ -352,4 +347,4 @@ if (!captionsContainer) { | ||
function loadMedia (url, type, startTime, thenPause) { | ||
playbackStrategy.load(url, type, startTime); | ||
function loadMedia (urls, type, startTime, thenPause) { | ||
playbackStrategy.load(urls, type, startTime); | ||
if (thenPause) { | ||
@@ -373,2 +368,7 @@ pause(); | ||
if (cdnDebugOutput) { | ||
cdnDebugOutput.tearDown(); | ||
cdnDebugOutput = undefined; | ||
} | ||
isInitialPlay = true; | ||
@@ -375,0 +375,0 @@ captionsURL = undefined; |
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
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
7540095
92
71700
1