diff --git a/samples/advanced/listening-to-SCTE-EMSG-events.html b/samples/advanced/listening-to-SCTE-EMSG-events.html index 7c30c83005..4472e7356b 100644 --- a/samples/advanced/listening-to-SCTE-EMSG-events.html +++ b/samples/advanced/listening-to-SCTE-EMSG-events.html @@ -32,7 +32,7 @@ function init() { player = dashjs.MediaPlayer().create(); - player.updateSettings({ 'debug': { 'logLevel': dashjs.Debug.LOG_LEVEL_NONE }}); + player.updateSettings({ 'debug': { 'logLevel': dashjs.Debug.LOG_LEVEL_DEBUG }}); player.on(SCHEMEIDURI, showStartEvent, null); /* Default mode is onStart, no need to specify a mode */ player.on(SCHEMEIDURI, showReceiveEvent, null, { mode: EVENT_MODE_ON_RECEIVE }); player.initialize(document.querySelector("video"), URL, true); diff --git a/src/core/Settings.js b/src/core/Settings.js index 2bd2b2ce59..055fa2416c 100644 --- a/src/core/Settings.js +++ b/src/core/Settings.js @@ -767,7 +767,7 @@ function Settings() { cacheInitSegments: false, applyServiceDescription: true, applyProducerReferenceTime: true, - eventControllerRefreshDelay: 150, + eventControllerRefreshDelay: 100, capabilities: { filterUnsupportedEssentialProperties: true, useMediaCapabilitiesApi: false diff --git a/src/dash/DashAdapter.js b/src/dash/DashAdapter.js index 2ab062df56..202fc6ef86 100644 --- a/src/dash/DashAdapter.js +++ b/src/dash/DashAdapter.js @@ -510,18 +510,21 @@ function DashAdapter() { * @instance * @ignore */ - function getEventsFor(info, voRepresentation) { + function getEventsFor(info, voRepresentation, streamInfo) { let events = []; if (voPeriods.length > 0) { const manifest = voPeriods[0].mpd.manifest; if (info instanceof StreamInfo) { - events = dashManifestModel.getEventsForPeriod(getPeriodForStreamInfo(info, voPeriods)); + const period = getPeriodForStreamInfo(info, voPeriods) + events = dashManifestModel.getEventsForPeriod(period); } else if (info instanceof MediaInfo) { - events = dashManifestModel.getEventStreamForAdaptationSet(manifest, getAdaptationForMediaInfo(info)); + const period = getPeriodForStreamInfo(streamInfo, voPeriods) + events = dashManifestModel.getEventStreamForAdaptationSet(manifest, getAdaptationForMediaInfo(info), period); } else if (info instanceof RepresentationInfo) { - events = dashManifestModel.getEventStreamForRepresentation(manifest, voRepresentation); + const period = getPeriodForStreamInfo(streamInfo, voPeriods) + events = dashManifestModel.getEventStreamForRepresentation(manifest, voRepresentation, period); } } diff --git a/src/dash/models/DashManifestModel.js b/src/dash/models/DashManifestModel.js index 6d4525328f..1b9a736520 100644 --- a/src/dash/models/DashManifestModel.js +++ b/src/dash/models/DashManifestModel.js @@ -165,7 +165,7 @@ function DashManifestModel() { function getProducerReferenceTimesForAdaptation(adaptation) { const prtArray = adaptation && adaptation.hasOwnProperty(DashConstants.PRODUCERREFERENCETIME_ASARRAY) ? adaptation[DashConstants.PRODUCERREFERENCETIME_ASARRAY] : []; - + // ProducerReferenceTime elements can also be contained in Representations const representationsArray = adaptation && adaptation.hasOwnProperty(DashConstants.REPRESENTATION_ASARRAY) ? adaptation[DashConstants.REPRESENTATION_ASARRAY] : []; @@ -206,7 +206,7 @@ function DashManifestModel() { // UTC element contained must be same as that in the MPD prtsForAdaptation.push(entry); }) - + return prtsForAdaptation; } @@ -932,7 +932,7 @@ function DashManifestModel() { return events; } - function getEventStreams(inbandStreams, representation) { + function getEventStreams(inbandStreams, representation, period) { const eventStreams = []; let i; @@ -955,12 +955,13 @@ function DashManifestModel() { eventStream.value = inbandStreams[i].value; } eventStreams.push(eventStream); + eventStream.period = period; } return eventStreams; } - function getEventStreamForAdaptationSet(manifest, adaptation) { + function getEventStreamForAdaptationSet(manifest, adaptation, period) { let inbandStreams, periodArray, adaptationArray; @@ -975,10 +976,10 @@ function DashManifestModel() { } } - return getEventStreams(inbandStreams, null); + return getEventStreams(inbandStreams, null, period); } - function getEventStreamForRepresentation(manifest, representation) { + function getEventStreamForRepresentation(manifest, representation, period) { let inbandStreams, periodArray, adaptationArray, @@ -997,7 +998,7 @@ function DashManifestModel() { } } - return getEventStreams(inbandStreams, representation); + return getEventStreams(inbandStreams, representation, period); } function getUTCTimingSources(manifest) { diff --git a/src/streaming/Stream.js b/src/streaming/Stream.js index 9e6bfb1fab..3f782f70d1 100644 --- a/src/streaming/Stream.js +++ b/src/streaming/Stream.js @@ -274,7 +274,7 @@ function Stream(config) { checkConfig(); isUpdating = true; - addInlineEvents(); + _addInlineEvents(); let element = videoModel.getElement(); @@ -694,10 +694,12 @@ function Stream(config) { } } - function addInlineEvents() { + function _addInlineEvents() { if (eventController) { const events = adapter.getEventsFor(streamInfo); - eventController.addInlineEvents(events); + if (events && events.length > 0) { + eventController.addInlineEvents(events, streamInfo.id); + } } } @@ -787,7 +789,7 @@ function Stream(config) { function onInbandEvents(e) { if (eventController) { - eventController.addInbandEvents(e.events); + eventController.addInbandEvents(e.events, streamInfo.id); } } @@ -842,7 +844,7 @@ function Stream(config) { streamInfo = updatedStreamInfo; if (eventController) { - addInlineEvents(); + _addInlineEvents(); } let promises = []; diff --git a/src/streaming/StreamProcessor.js b/src/streaming/StreamProcessor.js index 6c8f9439e3..b2abe01e90 100644 --- a/src/streaming/StreamProcessor.js +++ b/src/streaming/StreamProcessor.js @@ -955,8 +955,8 @@ function StreamProcessor(config) { // If we switch tracks this event might be fired after the representations in the RepresentationController have been updated according to the new MediaInfo. // In this case there will be no currentRepresentation and voRepresentation matching the "old" quality if (currentRepresentation && voRepresentation) { - const eventStreamMedia = adapter.getEventsFor(currentRepresentation.mediaInfo); - const eventStreamTrack = adapter.getEventsFor(currentRepresentation, voRepresentation); + const eventStreamMedia = adapter.getEventsFor(currentRepresentation.mediaInfo, null, streamInfo); + const eventStreamTrack = adapter.getEventsFor(currentRepresentation, voRepresentation, streamInfo); if (eventStreamMedia && eventStreamMedia.length > 0 || eventStreamTrack && eventStreamTrack.length > 0) { const request = fragmentModel.getRequests({ diff --git a/src/streaming/controllers/EventController.js b/src/streaming/controllers/EventController.js index da23eabd61..3ea770a661 100644 --- a/src/streaming/controllers/EventController.js +++ b/src/streaming/controllers/EventController.js @@ -88,8 +88,8 @@ function EventController() { */ function _resetInitialSettings() { isStarted = false; - inlineEvents = {}; // Format inlineEvents[schemeIdUri] - inbandEvents = {}; // Format inlineEvents[schemeIdUri] + inlineEvents = {}; // Format inlineEvents[periodID][schemeIdUri] + inbandEvents = {}; // Format inbandEvents[periodID][schemeIdUri] eventInterval = null; eventHandlingInProgress = false; lastEventTimerCall = Date.now() / 1000; @@ -128,30 +128,108 @@ function EventController() { } } + /** + * Iterate through the eventList and trigger the events + */ + function _onEventTimer() { + try { + if (!eventHandlingInProgress) { + eventHandlingInProgress = true; + const currentVideoTime = playbackController.getTime(); + let presentationTimeThreshold = (currentVideoTime - lastEventTimerCall); + + // For dynamic streams lastEventTimeCall will be large in the first iteration. Avoid firing all events at once. + presentationTimeThreshold = lastEventTimerCall > 0 ? Math.max(0, presentationTimeThreshold) : 0; + + _triggerEvents(inbandEvents, presentationTimeThreshold, currentVideoTime); + _triggerEvents(inlineEvents, presentationTimeThreshold, currentVideoTime); + _removeOutdatedEventObjects(inbandEvents); + _removeOutdatedEventObjects(inlineEvents); + + lastEventTimerCall = currentVideoTime; + eventHandlingInProgress = false; + } + } catch (e) { + eventHandlingInProgress = false; + logger.error(e); + } + } + + /** + * Iterate over a list of events and trigger the ones for which the presentation time is within the current timing interval + * @param {object} events + * @param {number} presentationTimeThreshold + * @param {number} currentVideoTime + * @private + */ + function _triggerEvents(events, presentationTimeThreshold, currentVideoTime) { + try { + const callback = function (event) { + if (event !== undefined) { + const duration = !isNaN(event.duration) ? event.duration : 0; + // The event is either about to start or has already been started and we are within its duration + if ((event.calculatedPresentationTime <= currentVideoTime && event.calculatedPresentationTime + presentationTimeThreshold + duration >= currentVideoTime)) { + _startEvent(event, MediaPlayerEvents.EVENT_MODE_ON_START); + } else if (_eventHasExpired(currentVideoTime, duration + presentationTimeThreshold, event.calculatedPresentationTime) || _eventIsInvalid(event)) { + logger.debug(`Removing event ${event.id} from period ${event.eventStream.period.id} as it is expired or invalid`); + _removeEvent(events, event); + } + } + }; + + _iterateAndTriggerCallback(events, callback); + } catch (e) { + logger.error(e); + } + } + + /** + * Iterates over the entries of the events object and deletes the entries for which no events are present + * @param {object} events + * @private + */ + function _removeOutdatedEventObjects(events) { + try { + for (const key in events) { + if (events.hasOwnProperty(key)) { + if (Object.keys(events[key]).length === 0) + delete events[key]; + } + } + } catch (e) { + logger.error(e); + } + } + /** * Add MPD events to the list of events. * Events that are not in the MPD anymore but not triggered yet will still be deleted. * Existing events might get updated. * @param {Array.} values + * @param {string} periodId */ - function addInlineEvents(values) { + function addInlineEvents(values, periodId) { try { checkConfig(); + if (!inlineEvents[periodId]) { + inlineEvents[periodId] = {}; + } + if (values) { for (let i = 0; i < values.length; i++) { let event = values[i]; const currentTime = playbackController.getTime(); const duration = !isNaN(event.duration) ? event.duration : 0; if (!_eventHasExpired(currentTime, duration, event.calculatedPresentationTime)) { - let result = _addOrUpdateEvent(event, inlineEvents, true); + let result = _addOrUpdateEvent(event, inlineEvents[periodId], true); if (result === EVENT_HANDLED_STATES.ADDED) { - logger.debug(`Added inline event with id ${event.id}`); + logger.debug(`Added inline event with id ${event.id} from period ${periodId}`); // If we see the event for the first time we trigger it in onReceive mode - _startEvent(event, values, MediaPlayerEvents.EVENT_MODE_ON_RECEIVE); + _startEvent(event, MediaPlayerEvents.EVENT_MODE_ON_RECEIVE); } else if (result === EVENT_HANDLED_STATES.UPDATED) { - logger.debug(`Updated inline event with id ${event.id}`); + logger.debug(`Updated inline event with id ${event.id} from period ${periodId}`); } } } @@ -165,26 +243,31 @@ function EventController() { * Add EMSG events to the list of events * Messages with the same id within the scope of the same scheme_id_uri and value pair are equivalent , i.e. processing of any one event message box with the same id is sufficient. * @param {Array.} values + * @param {string} periodId */ - function addInbandEvents(values) { + function addInbandEvents(values, periodId) { try { checkConfig(); + if (!inbandEvents[periodId]) { + inbandEvents[periodId] = {}; + } + for (let i = 0; i < values.length; i++) { let event = values[i]; const currentTime = playbackController.getTime(); const duration = !isNaN(event.duration) ? event.duration : 0; if (!_eventHasExpired(currentTime, duration, event.calculatedPresentationTime)) { - let result = _addOrUpdateEvent(event, inbandEvents, false); + let result = _addOrUpdateEvent(event, inbandEvents[periodId], false); if (result === EVENT_HANDLED_STATES.ADDED) { - if (event.eventStream.schemeIdUri === MPD_RELOAD_SCHEME && inbandEvents[event.id] === undefined) { + if (event.eventStream.schemeIdUri === MPD_RELOAD_SCHEME) { _handleManifestReloadEvent(event); } - logger.debug('Added inband event with id ' + event.id); - _startEvent(event, values, MediaPlayerEvents.EVENT_MODE_ON_RECEIVE); + logger.debug(`Added inband event with id ${event.id} from period ${periodId}`); + _startEvent(event, MediaPlayerEvents.EVENT_MODE_ON_RECEIVE); } else { - logger.debug(`Inband event with scheme_id_uri ${event.eventStream.schemeIdUri}, value ${event.eventStream.value} and id ${event.id} was ignored because it has been added before.`); + logger.debug(`Inband event with scheme_id_uri ${event.eventStream.schemeIdUri}, value ${event.eventStream.value}, period id ${periodId} and event id ${event.id} was ignored because it has been added before.`); } } } @@ -216,12 +299,16 @@ function EventController() { return ((!value || (e.eventStream.value && e.eventStream.value === value)) && (e.id === id)); }); + // New event, we add it to our list of events if (indexOfExistingEvent === -1) { events[schemeIdUri].push(event); event.triggeredReceivedEvent = false; event.triggeredStartEvent = false; eventState = EVENT_HANDLED_STATES.ADDED; - } else if (shouldOverwriteExistingEvents) { + } + + // We have a similar event for this period with the same schemeIdUri, value and id. Overwrite it or ignore it + else if (shouldOverwriteExistingEvents) { const oldEvent = events[schemeIdUri][indexOfExistingEvent]; event.triggeredReceivedEvent = oldEvent.triggeredReceivedEvent; event.triggeredStartEvent = oldEvent.triggeredStartEvent; @@ -258,30 +345,7 @@ function EventController() { }); } } catch (e) { - } - } - - /** - * Iterate through the eventList and trigger the events - */ - function _onEventTimer() { - try { - if (!eventHandlingInProgress) { - eventHandlingInProgress = true; - const currentVideoTime = playbackController.getTime(); - let presentationTimeThreshold = (currentVideoTime - lastEventTimerCall); - - // For dynamic streams lastEventTimeCall will be large in the first iteration. Avoid firing all events at once. - presentationTimeThreshold = lastEventTimerCall > 0 ? Math.max(0, presentationTimeThreshold) : 0; - - _triggerEvents(inbandEvents, presentationTimeThreshold, currentVideoTime); - _triggerEvents(inlineEvents, presentationTimeThreshold, currentVideoTime); - - lastEventTimerCall = currentVideoTime; - eventHandlingInProgress = false; - } - } catch (e) { - eventHandlingInProgress = false; + logger.error(e); } } @@ -295,34 +359,7 @@ function EventController() { _triggerRemainingEvents(inbandEvents); _triggerRemainingEvents(inlineEvents); } catch (e) { - - } - } - - /** - * Iterate over a list of events and trigger the ones for which the presentation time is within the current timing interval - * @param {object} events - * @param {number} presentationTimeThreshold - * @param {number} currentVideoTime - * @private - */ - function _triggerEvents(events, presentationTimeThreshold, currentVideoTime) { - try { - const callback = function (event) { - if (event !== undefined) { - const duration = !isNaN(event.duration) ? event.duration : 0; - // The event is either about to start or has already been started and we are within its duration - if ((event.calculatedPresentationTime <= currentVideoTime && event.calculatedPresentationTime + presentationTimeThreshold + duration >= currentVideoTime)) { - _startEvent(event, events, MediaPlayerEvents.EVENT_MODE_ON_START); - } else if (_eventHasExpired(currentVideoTime, duration + presentationTimeThreshold, event.calculatedPresentationTime) || _eventIsInvalid(event)) { - logger.debug(`Deleting event ${event.id} as it is expired or invalid`); - _removeEvent(events, event); - } - } - }; - - _iterateAndTriggerCallback(events, callback); - } catch (e) { + logger.error(e); } } @@ -345,7 +382,7 @@ function EventController() { const calculatedPresentationTimeInSeconds = event.calculatedPresentationTime; if (Math.abs(calculatedPresentationTimeInSeconds - currentTime) < REMAINING_EVENTS_THRESHOLD) { - _startEvent(event, events, MediaPlayerEvents.EVENT_MODE_ON_START); + _startEvent(event, MediaPlayerEvents.EVENT_MODE_ON_START); } }; @@ -353,7 +390,7 @@ function EventController() { _iterateAndTriggerCallback(events, callback); } catch (e) { - + logger.error(e); } } @@ -366,18 +403,22 @@ function EventController() { function _iterateAndTriggerCallback(events, callback) { try { if (events) { - const schemeIdUris = Object.keys(events); - for (let i = 0; i < schemeIdUris.length; i++) { - const schemeIdEvents = events[schemeIdUris[i]]; - schemeIdEvents.forEach((event) => { - if (event !== undefined) { - callback(event); - } - }); + const periodIds = Object.keys(events); + for (let i = 0; i < periodIds.length; i++) { + const currentPeriod = events[periodIds[i]]; + const schemeIdUris = Object.keys(currentPeriod); + for (let j = 0; j < schemeIdUris.length; j++) { + const schemeIdEvents = currentPeriod[schemeIdUris[j]]; + schemeIdEvents.forEach((event) => { + if (event !== undefined) { + callback(event); + } + }); + } } } } catch (e) { - + logger.error(e); } } @@ -393,6 +434,7 @@ function EventController() { try { return currentVideoTime - threshold > calculatedPresentationTimeInSeconds; } catch (e) { + logger.error(e); return false; } } @@ -409,6 +451,7 @@ function EventController() { return event.calculatedPresentationTime > periodEndTime; } catch (e) { + logger.error(e); return false; } } @@ -419,19 +462,18 @@ function EventController() { * - MPD Callback events * - Events to be dispatched to the application * @param {object} event - * @param {object} events * @param {String} mode * @private */ - function _startEvent(event, events, mode) { + function _startEvent(event, mode) { try { const currentVideoTime = playbackController.getTime(); const eventId = event.id; if (mode === MediaPlayerEvents.EVENT_MODE_ON_RECEIVE && !event.triggeredReceivedEvent) { logger.debug(`Received event ${eventId}`); - eventBus.trigger(event.eventStream.schemeIdUri, { event: event }, { mode }); event.triggeredReceivedEvent = true; + eventBus.trigger(event.eventStream.schemeIdUri, { event: event }, { mode }); return; } @@ -446,12 +488,13 @@ function EventController() { logger.debug(`Starting callback event ${eventId} at ${currentVideoTime}`); _sendCallbackRequest(event.messageData); } else { - logger.debug(`Starting event ${eventId} at ${currentVideoTime}`); + logger.debug(`Starting event ${eventId} from period ${event.eventStream.period.id} at ${currentVideoTime}`); eventBus.trigger(event.eventStream.schemeIdUri, { event: event }, { mode }); } event.triggeredStartEvent = true; } } catch (e) { + logger.error(e); } } @@ -462,18 +505,22 @@ function EventController() { * @private */ function _removeEvent(events, event) { - const schemeIdUri = event.eventStream.schemeIdUri; - const value = event.eventStream.value; - const id = event.id; + try { + const schemeIdUri = event.eventStream.schemeIdUri; + const periodId = event.eventStream.period.id; + const value = event.eventStream.value; + const id = event.id; - events[schemeIdUri] = events[schemeIdUri].filter((e) => { - return (value && e.eventStream.value && e.eventStream.value !== value) || e.id !== id; - }); + events[periodId][schemeIdUri] = events[periodId][schemeIdUri].filter((e) => { + return (value && e.eventStream.value && e.eventStream.value !== value) || e.id !== id; + }); - if (events[schemeIdUri].length === 0) { - delete events[schemeIdUri]; + if (events[periodId][schemeIdUri].length === 0) { + delete events[periodId][schemeIdUri]; + } + } catch (e) { + logger.error(e); } - } /** @@ -485,6 +532,7 @@ function EventController() { checkConfig(); manifestUpdater.refreshManifest(); } catch (e) { + logger.error(e); } } @@ -504,7 +552,7 @@ function EventController() { } }); } catch (e) { - throw e; + logger.error(e); } } diff --git a/test/unit/streaming.controllers.EventController.js b/test/unit/streaming.controllers.EventController.js index 7ef0ace2d4..f24e7608ee 100644 --- a/test/unit/streaming.controllers.EventController.js +++ b/test/unit/streaming.controllers.EventController.js @@ -66,12 +66,16 @@ describe('EventController', function () { }); it('should add a single inband event with a value and trigger it', function (done) { - const schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; const value = 'value'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 1, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', value, @@ -90,16 +94,20 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInbandEvent, this); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); }); it('should add a single inband event without a value and trigger it', function (done) { - const schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 1, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 0 @@ -117,18 +125,22 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInbandEvent, this); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); }); it('should add a two inband events with different values and same id and trigger them', function (done) { - const schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [ { eventStream: { timescale: 1, schemeIdUri: schemeIdUri, - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 0 @@ -137,7 +149,10 @@ describe('EventController', function () { eventStream: { timescale: 1, schemeIdUri: schemeIdUri, - value: 'value2' + value: 'value2', + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 0 @@ -159,18 +174,22 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInbandEvent, this); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); }); it('should add a two inband events with different ids and same values and trigger them', function (done) { - const schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [ { eventStream: { timescale: 1, schemeIdUri: schemeIdUri, - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 0 @@ -179,7 +198,10 @@ describe('EventController', function () { eventStream: { timescale: 1, schemeIdUri: schemeIdUri, - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event1', calculatedPresentationTime: 0 @@ -201,17 +223,21 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInbandEvent, this); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); }); it('should add a two inband events with different scheme ids and same id and value fields and trigger them', function (done) { + const periodId = 'periodId'; let events = [ { eventStream: { timescale: 1, schemeIdUri: 'inbandEvent1', - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 0 @@ -220,7 +246,10 @@ describe('EventController', function () { eventStream: { timescale: 1, schemeIdUri: 'inbandEvent2', - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 0 @@ -244,18 +273,22 @@ describe('EventController', function () { eventBus.on('inbandEvent1', onInbandEvent, this); eventBus.on('inbandEvent2', onInbandEvent, this); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); }); it('should add only one out of two similar events and trigger it', function (done) { - const schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [ { eventStream: { timescale: 1, schemeIdUri: schemeIdUri, - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event0', messageData: '1', @@ -265,7 +298,10 @@ describe('EventController', function () { eventStream: { timescale: 1, schemeIdUri: schemeIdUri, - value: 'value1' + value: 'value1', + period: { + id: periodId + } }, id: 'event0', messageData: '2', @@ -285,17 +321,21 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInbandEvent, this); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); }); it('should trigger added inline events', function (done) { - let schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; const value = 'value'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 1, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', value, @@ -314,18 +354,22 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInlineEvent, this); - eventController.addInlineEvents(events); + eventController.addInlineEvents(events, periodId); eventController.start(); }); it('should add inline event twice, updating first event', function (done) { - let schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; const value = 'value'; + const periodId = 'periodId'; let events = [ { eventStream: { timescale: 1, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', value, @@ -335,7 +379,10 @@ describe('EventController', function () { { eventStream: { timescale: 1, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', value, @@ -356,16 +403,20 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onInlineEvent, this); - eventController.addInlineEvents(events); + eventController.addInlineEvents(events, periodId); eventController.start(); }); it('should trigger added inline events', function (done) { - let schemeIdUri = 'inbandEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 1, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 20 @@ -391,18 +442,22 @@ describe('EventController', function () { }; eventBus.on(schemeIdUri, onStartEvent, this, { mode: MediaPlayerEvents.EVENT_MODE_ON_START }); - eventController.addInbandEvents(events); + eventController.addInbandEvents(events, periodId); eventController.start(); playbackControllerMock.setTime(20); }); it('should trigger an inline event that has already been started and is still running', function (done) { - let schemeIdUri = 'inlineEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 3, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 10, @@ -422,7 +477,7 @@ describe('EventController', function () { }; eventBus.on(schemeIdUri, onStartEvent, this, { mode: MediaPlayerEvents.EVENT_MODE_ON_START }); - eventController.addInlineEvents(events); + eventController.addInlineEvents(events, periodId); eventController.start(); playbackControllerMock.setTime(20); @@ -430,11 +485,15 @@ describe('EventController', function () { it('should not trigger an inline event for which the start + duration has already expired', function () { let triggerCount = 0; - let schemeIdUri = 'inlineEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 3, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 10, @@ -446,7 +505,7 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onStartEvent, this, { mode: MediaPlayerEvents.EVENT_MODE_ON_START }); - eventController.addInlineEvents(events); + eventController.addInlineEvents(events, periodId); eventController.start(); playbackControllerMock.setTime(20); @@ -458,11 +517,15 @@ describe('EventController', function () { it('should not fire inline events in onReceive mode twice', function () { let triggerCount = 0; - let schemeIdUri = 'inlineEvent'; + const schemeIdUri = 'schemeIdUri'; + const periodId = 'periodId'; let events = [{ eventStream: { timescale: 3, - schemeIdUri: schemeIdUri + schemeIdUri: schemeIdUri, + period: { + id: periodId + } }, id: 'event0', calculatedPresentationTime: 10, @@ -474,8 +537,8 @@ describe('EventController', function () { eventBus.on(schemeIdUri, onReceiveEvent, this, { mode: MediaPlayerEvents.EVENT_MODE_ON_RECEIVE }); - eventController.addInlineEvents(events); - eventController.addInlineEvents(events); + eventController.addInlineEvents(events, periodId); + eventController.addInlineEvents(events, periodId); expect(triggerCount).to.equal(1); @@ -494,7 +557,7 @@ describe('EventController', function () { eventBus.on(MediaPlayerEvents.MANIFEST_VALIDITY_CHANGED, manifestValidityExpiredHandler, this); - eventController.addInbandEvents([manifestExpiredEventStub]); + eventController.addInbandEvents([manifestExpiredEventStub], 'periodId'); }); it('should not fire manifest validity expiration events if an event with that ID has already been received', function () { @@ -505,8 +568,8 @@ describe('EventController', function () { eventBus.on(MediaPlayerEvents.MANIFEST_VALIDITY_CHANGED, manifestValidityExpiredHandler, this); - eventController.addInbandEvents([manifestExpiredEventStub]); - eventController.addInbandEvents([manifestExpiredEventStub]); + eventController.addInbandEvents([manifestExpiredEventStub], 'periodId'); + eventController.addInbandEvents([manifestExpiredEventStub], 'periodId'); expect(triggerCount).to.equal(1);