diff --git a/index.d.ts b/index.d.ts index 505166ae37..3c9b948052 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3707,7 +3707,7 @@ declare namespace dashjs { update(manifest: object): void; } - export interface CmcdModel { + export interface CmcdController { getCmcdData(request: HTTPRequest): object; getCmcdParametersFromManifest(): CMCDParameters; diff --git a/samples/advanced/cmcdv2-network-interceptors.html b/samples/advanced/cmcdv2-network-interceptors.html new file mode 100644 index 0000000000..f46a515f38 --- /dev/null +++ b/samples/advanced/cmcdv2-network-interceptors.html @@ -0,0 +1,187 @@ + + + + + CMCD Callbacks with Network Interceptors + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+

CMCD Reporting

+

This sample shows how to use Network Interceptors to execute callbacks after server response or pre-request callbacks for Response and Event Mode

+
+
+
+
+
+ +
+
+
+ + +
+
+
+
+
+
+
+
+ +
+
+ + + + + + diff --git a/samples/players-synchronization/globalSync.html b/samples/players-synchronization/globalSync.html new file mode 100644 index 0000000000..f5e01f1bd5 --- /dev/null +++ b/samples/players-synchronization/globalSync.html @@ -0,0 +1,95 @@ + + + + + + Follower client + + + + + + + + + + + + +
+
+
+

Follower client

+
+
+
+
+ + + +
+ +
+
+ +
+
+ + + + + \ No newline at end of file diff --git a/samples/players-synchronization/playerSynchronizationPlugin.js b/samples/players-synchronization/playerSynchronizationPlugin.js new file mode 100644 index 0000000000..d1669ba605 --- /dev/null +++ b/samples/players-synchronization/playerSynchronizationPlugin.js @@ -0,0 +1,194 @@ +const CMCD_MODE_QUERY = 'query'; +let leaderTimestamp; +let leaderPlayhead; +let playbackRate; + +let lastInterval; + +(() => { + const syncPlayer = (player, config) => { + if (!leaderTimestamp || !leaderPlayhead || !playbackRate) { + return; + } + + const currentTimestamp = Date.now(); + const timeElapsed = (currentTimestamp - leaderTimestamp) / 1000; + const timeToSeek = leaderPlayhead + timeElapsed * playbackRate; + + const currentRepresentation = player.getCurrentRepresentationForType('video'); + const currentFrameRate = currentRepresentation.frameRate; + const frameDelay = Math.min(config.frameDelay, currentFrameRate); + + const SEEK_THRESHOLD = config.seekThreshold ?? (currentFrameRate / 100); + const SYNC_THRESHOLD = (currentFrameRate / 1000) * frameDelay; + + const getPlayersTimeDifference = () => Math.abs(timeToSeek - player.time()); + + const playersDifference = getPlayersTimeDifference(); + if (playersDifference > SEEK_THRESHOLD) { + player.seekToPresentationTime(timeToSeek); + player.setPlaybackRate(playbackRate); + if (lastInterval) { + clearInterval(lastInterval); + lastInterval = null; + } + } else if (playersDifference > SYNC_THRESHOLD) { + if (lastInterval) { + return; + } + + const isAheadOfTheLeader = player.time() > timeToSeek; + const catchUpRate = Math.max(config.catchUpRate, 1); + const speedModification = isAheadOfTheLeader ? 1 / catchUpRate : catchUpRate; + + player.setPlaybackRate(speedModification * playbackRate); + const interval = setInterval(() => { + lastInterval = interval; + const currentDifference = getPlayersTimeDifference(); + if (currentDifference <= SYNC_THRESHOLD) { + player.setPlaybackRate(playbackRate); + lastInterval = null; + clearInterval(interval); + } else if (currentDifference > SEEK_THRESHOLD) { + player.seekToPresentationTime(timeToSeek); + player.setPlaybackRate(playbackRate); + lastInterval = null; + clearInterval(interval); + } + }, 10); + } + }; + + const setupCMCD = (player, config) => { + player.updateSettings({ + streaming: { + cmcd: { + enabled: true, + version: 2, + reporting: { + eventMode: { + enabled: true, + mode: CMCD_MODE_QUERY, + interval: 5000, + enabledKeys: ['sid', 'cid', 'pr', 'pt', 'ts'], + requestUrl: config.url, + requestMethod: 'POST', + } + }, + sid: config.id, + mode: CMCD_MODE_QUERY, + } + } + }); + }; + + const parseCMSDHeader = (response) => { + const cmsdHeader = response.headers.get('cmsd-dynamic'); + + if (!cmsdHeader) { + return null; + } + + const latencyMatch = cmsdHeader.match(/com\.svta-latency="([^"]+)"/); + const latencyTargetsMatch = cmsdHeader.match(/com\.svta-latency-targets="([^"]+)"/); + + const latency = latencyMatch ? Number(latencyMatch[1]) : null; + const latencyTargets = latencyTargetsMatch ? latencyTargetsMatch[1].split(',').map(Number) : null; + + return { latency, latencyTargets }; + }; + + const configInterceptors = (player, config) => { + if (config.globalSync) { + globalSyncInterceptor(player, config); + } else if (config.leaderId) { + leaderSyncInterceptor(player, config); + } + + } + + const globalSyncInterceptor = (player) => { + player.addResponseInterceptor((response) => { + if (response.cmcdMode !== 'event') { + return Promise.resolve(response); + } + + const cmsdData = parseCMSDHeader(response); + + if (cmsdData) { + const { latency } = cmsdData; + if (latency) { + player.updateSettings({ + streaming: { + delay: { + liveDelay: latency + }, + liveCatchup: { + enabled: true, + } + } + }); + } + } + return Promise.resolve(response); + }); + } + + const leaderSyncInterceptor = (player, config) => { + player.addRequestInterceptor((request) => { + const { filteredCmcdData } = request; + if (filteredCmcdData) { + filteredCmcdData['synchronization-leader-sid'] = config.leaderId; + } + return Promise.resolve(request); + }); + + let firstRun = true; + player.addResponseInterceptor((response) => { + if (response.cmcdMode === 'event') { + response.json().then((data) => { + if (!data || !data.ts || !data.pt) { + return Promise.resolve(response); + } + const { ts, pt, pr } = data; + leaderTimestamp = Number(ts); + leaderPlayhead = Number(pt); + playbackRate = Number(pr ?? 1); + + if (firstRun) { + syncPlayer(player, config); + firstRun = false; + } + + return Promise.resolve(response); + }); + } + return Promise.resolve(response); + }); + } + + + window.playerSynchronization = { + addLeader(player, config) { + setupCMCD(player, config); + }, + addFollower(player, config) { + setupCMCD(player, config); + configInterceptors(player, config); + if (config.globalSync) { + return; + } + setInterval(() => { + syncPlayer(player, config); + }, config.syncInterval ?? 5000); + + let seeking = false; + player.on(dashjs.MediaPlayer.events.PLAYBACK_SEEKED, () => { + if (!seeking) { + syncPlayer(player, config); + seeking = true; + } + }); + } + }; +})(); diff --git a/samples/samples.json b/samples/samples.json index 2c4ed57914..9f34f69de0 100644 --- a/samples/samples.json +++ b/samples/samples.json @@ -708,6 +708,17 @@ "Audio" ] }, + { + "title": "CMCD Callbacks with Network Interceptors", + "description": "This sample shows how to use Network Interceptors to execute callbacks after server response or pre-request callbacks for Response and Event Mode", + "href": "advanced/cmcdv2-network-interceptors.html", + "image": "lib/img/bbb-1.jpg", + "labels": [ + "VoD", + "Video", + "Audio" + ] + }, { "title": "Flexible Insertion of URL Parameters Sample", "description": "This sample demonstrates the Flexible Insertion of URL Parameters in dash.js.", diff --git a/src/core/Settings.js b/src/core/Settings.js index 46f3ec646a..b5a570665d 100644 --- a/src/core/Settings.js +++ b/src/core/Settings.js @@ -912,8 +912,28 @@ import Events from './events/Events.js'; * The version of the CMCD to use. * * If not specified this value defaults to 1. + * @property {Array.} [targets] + * List of CMCD reporting targets. */ +/** + * @typedef {Object} CmcdTarget + * @property {string} [mode] + * Mode of the CMCD reporting. + * @property {boolean} [enabled] + * Whether the CMCD reporting is enabled for this target. + * @property {string} [url] + * The reporting endpoint URL. + * @property {string} [events] + * The events that should trigger the CMCD reporting. + * @property {string} [timeInterval] + * The time interval for the CMCD reporting in event mode. The 't' event should be setted in the events array to use this parameter. + * @property {Array.} [enabledKeys] + * CMCD keys to include in the report. + * @property {Array.} [includeOnRequests] + * Types of requests CMCD should be included on (e.g., 'mpd', 'segment'). +*/ + /** * @typedef {Object} module:Settings~CmsdSettings * @property {boolean} [enabled=false] @@ -1361,7 +1381,8 @@ function Settings() { mode: Constants.CMCD_MODE_QUERY, enabledKeys: Constants.CMCD_AVAILABLE_KEYS, includeInRequests: ['segment', 'mpd'], - version: 1 + version: 1, + targets: [] }, cmsd: { enabled: false, diff --git a/src/streaming/MediaPlayer.js b/src/streaming/MediaPlayer.js index 8daf5f8722..293ad564ae 100644 --- a/src/streaming/MediaPlayer.js +++ b/src/streaming/MediaPlayer.js @@ -50,7 +50,7 @@ import MediaPlayerModel from './models/MediaPlayerModel.js'; import AbrController from './controllers/AbrController.js'; import SchemeLoaderFactory from './net/SchemeLoaderFactory.js'; import VideoModel from './models/VideoModel.js'; -import CmcdModel from './models/CmcdModel.js'; +import CmcdController from './controllers/CmcdController.js'; import CmsdModel from './models/CmsdModel.js'; import DOMStorage from './utils/DOMStorage.js'; import Debug from './../core/Debug.js'; @@ -164,7 +164,7 @@ function MediaPlayer() { catchupController, dashMetrics, manifestModel, - cmcdModel, + cmcdController, cmsdModel, videoModel, uriFragmentModel, @@ -356,7 +356,7 @@ function MediaPlayer() { manifestModel = ManifestModel(context).getInstance(); - cmcdModel = CmcdModel(context).getInstance(); + cmcdController = CmcdController(context).getInstance(); cmsdModel = CmsdModel(context).getInstance(); @@ -2398,7 +2398,7 @@ function MediaPlayer() { } } textController.reset(); - cmcdModel.reset(); + cmcdController.reset(); cmsdModel.reset(); } @@ -2504,12 +2504,14 @@ function MediaPlayer() { settings }); - cmcdModel.setConfig({ + cmcdController.setConfig({ abrController, dashMetrics, playbackController, serviceDescriptionController, throughputController, + mediaPlayerModel, + errHandler }); clientDataReportingController.setConfig({ @@ -2526,7 +2528,7 @@ function MediaPlayer() { textController.initialize(); gapController.initialize(); catchupController.initialize(); - cmcdModel.initialize(autoPlay); + cmcdController.initialize(autoPlay); cmsdModel.initialize(); contentSteeringController.initialize(); segmentBaseController.initialize(); @@ -2571,7 +2573,7 @@ function MediaPlayer() { events: Events, BASE64, constants: Constants, - cmcdModel, + cmcdController, settings }); diff --git a/src/streaming/constants/Constants.js b/src/streaming/constants/Constants.js index ce4443665b..b9eaa135da 100644 --- a/src/streaming/constants/Constants.js +++ b/src/streaming/constants/Constants.js @@ -214,7 +214,12 @@ export default { * @static */ CMCD_MODE_HEADER: 'header', - + /** + * @constant {string} CMCD_MANDATORY_KEYS specifies all the mandatory keys for all CMCD modes (Event Mode, Request Mode & Response Mode). + * @memberof Constants# + * @static + */ + CMCD_MANDATORY_KEYS: ['ts'], /** * @constant {string} CMCD_AVAILABLE_KEYS specifies all the available keys for CMCD metrics. * @memberof Constants# @@ -226,7 +231,7 @@ export default { * @memberof Constants# * @static */ - CMCD_V2_AVAILABLE_KEYS: ['msd', 'ltc'], + CMCD_V2_AVAILABLE_KEYS: ['e', 'msd', 'ltc'], /** * @constant {string} CMCD_AVAILABLE_REQUESTS specifies all the available requests type for CMCD metrics. @@ -235,6 +240,32 @@ export default { */ CMCD_AVAILABLE_REQUESTS: ['segment', 'mpd', 'xlink', 'steering', 'other'], + /** + * @constant {string} CMCD_MODE specifies all the available modes for CMCD. + * @memberof Constants# + * @static + */ + CMCD_MODE: { + REQUEST: 'request', + RESPONSE: 'response', + EVENT: 'event' + }, + + /** + * @constant {string} CMCD_REPORTING_EVENTS specifies all the available events for CMCD event mode. + * @memberof Constants# + * @static + */ + CMCD_REPORTING_EVENTS: { + START: 's', + PLAYING: 'p', + PAUSED : 'a', + SEEKING: 'k', + REBUFFERING: 'r', + FATAL_ERROR: 'f', + ENDED: 'e', + TIME_INTERVAL: 't' + }, INITIALIZE: 'initialize', TEXT_SHOWING: 'showing', diff --git a/src/streaming/models/CmcdModel.js b/src/streaming/controllers/CmcdController.js similarity index 68% rename from src/streaming/models/CmcdModel.js rename to src/streaming/controllers/CmcdController.js index ada7412eaa..5527a68504 100644 --- a/src/streaming/models/CmcdModel.js +++ b/src/streaming/controllers/CmcdController.js @@ -36,6 +36,7 @@ import Settings from '../../core/Settings.js'; import Constants from '../../streaming/constants/Constants.js'; import {HTTPRequest} from '../vo/metrics/HTTPRequest.js'; import DashManifestModel from '../../dash/models/DashManifestModel.js'; +import ClientDataReportingController from '../controllers/ClientDataReportingController.js'; import Debug from '../../core/Debug.js'; import Utils from '../../core/Utils.js'; import {CMCD_PARAM} from '@svta/common-media-library/cmcd/CMCD_PARAM'; @@ -45,11 +46,15 @@ import {CmcdStreamingFormat} from '@svta/common-media-library/cmcd/CmcdStreaming import {encodeCmcd} from '@svta/common-media-library/cmcd/encodeCmcd'; import {toCmcdHeaders} from '@svta/common-media-library/cmcd/toCmcdHeaders'; import {CmcdHeaderField} from '@svta/common-media-library/cmcd/CmcdHeaderField'; +import CmcdReportRequest from '../../streaming/vo/CmcdReportRequest.js'; +import URLLoader from '../net/URLLoader.js'; +import Errors from '../../core/errors/Errors.js'; + const DEFAULT_CMCD_VERSION = 1; const DEFAULT_INCLUDE_IN_REQUESTS = 'segment'; const RTP_SAFETY_FACTOR = 5; -function CmcdModel() { +function CmcdController() { let dashManifestModel, instance, @@ -59,14 +64,19 @@ function CmcdModel() { dashMetrics, playbackController, serviceDescriptionController, + errHandler, + mediaPlayerModel, throughputController, streamProcessors, + clientDataReportingController, _lastMediaTypeRequest, _isStartup, _bufferLevelStarved, _initialMediaRequestsDone, _playbackStartedTime, - _msdSent; + _msdSent, + urlLoader, + _isSeeking; let context = this.context; let eventBus = EventBus(context).getInstance(); @@ -75,6 +85,7 @@ function CmcdModel() { function setup() { dashManifestModel = DashManifestModel(context).getInstance(); + clientDataReportingController = ClientDataReportingController(context).getInstance(); logger = debug.getLogger(instance); _resetInitialSettings(); } @@ -92,7 +103,72 @@ function CmcdModel() { eventBus.on(MediaPlayerEvents.PLAYBACK_STARTED, _onPlaybackStarted, instance); } eventBus.on(MediaPlayerEvents.PLAYBACK_PLAYING, _onPlaybackPlaying, instance); + + _initializeEventModeTimeInterval(); + _initializeEventModeListeners(); + } + + function _initializeEventModeListeners() { + const eventStateMap = { + [MediaPlayerEvents.PLAYBACK_INITIALIZED]: Constants.CMCD_REPORTING_EVENTS.START, + [MediaPlayerEvents.PLAYBACK_STARTED]: Constants.CMCD_REPORTING_EVENTS.PLAYING, + [MediaPlayerEvents.PLAYBACK_PAUSED]: Constants.CMCD_REPORTING_EVENTS.PAUSED, + [MediaPlayerEvents.PLAYBACK_PLAYING]: Constants.CMCD_REPORTING_EVENTS.PLAYING, + [MediaPlayerEvents.PLAYBACK_ERROR]: Constants.CMCD_REPORTING_EVENTS.FATAL_ERROR, + [MediaPlayerEvents.PLAYBACK_ENDED]: Constants.CMCD_REPORTING_EVENTS.ENDED + }; + + eventBus.on(MediaPlayerEvents.PLAYBACK_SEEKING, _onPlaybackSeeking, instance); + eventBus.on(MediaPlayerEvents.PLAYBACK_WAITING, _onPlaybackWaiting, instance); + + Object.entries(eventStateMap).forEach(([event, state]) => { + eventBus.on(event, () => _onStateChange(state), instance); + }); } + + function _initializeEventModeTimeInterval() { + const targets = settings.get().streaming.cmcd.targets; + const eventModeTargets = targets.filter((target) => target.cmcdMode === Constants.CMCD_MODE.EVENT); + eventModeTargets.forEach(({ timeInterval }) => { + const triggerEventModeInterval = () => { + _onStateChange(Constants.CMCD_REPORTING_EVENTS.TIME_INTERVAL); + setTimeout(triggerEventModeInterval, (timeInterval * 1000)); + } + triggerEventModeInterval(); + }); + } + + function _onStateChange(state) { + const targets = settings.get().streaming.cmcd.targets; + const eventModeTargets = targets.filter((target) => target.cmcdMode === Constants.CMCD_MODE.EVENT); + + if (eventModeTargets.length === 0) { + return; + } + + const cmcdData = _getGenericCmcdData(); + cmcdData.e = state; + + eventModeTargets.forEach(targetSettings => { + if (targetSettings.enabled) { + let events = targetSettings.events ? targetSettings.events : Object.values(Constants.CMCD_REPORTING_EVENTS); + + if (!events.includes(state)) { + return; + } + + let httpRequest = new CmcdReportRequest(); + + httpRequest.url = targetSettings.url; + httpRequest.type = HTTPRequest.CMCD_EVENT; + httpRequest.method = HTTPRequest.GET; + + _updateRequestUrlAndHeadersWithCmcd(httpRequest, cmcdData, targetSettings) + _sendCmcdDataReport(httpRequest); + } + }); + } + function setConfig(config) { if (!config) { @@ -118,6 +194,15 @@ function CmcdModel() { if (config.serviceDescriptionController) { serviceDescriptionController = config.serviceDescriptionController; } + + if (config.mediaPlayerModel) { + mediaPlayerModel = config.mediaPlayerModel; + } + + if (config.mediaPlayerModel) { + errHandler = config.errHandler; + } + } function _resetInitialSettings() { @@ -174,16 +259,21 @@ function CmcdModel() { streamProcessors = activeStream.getStreamProcessors(); } - function getQueryParameter(request) { + function getQueryParameter(request, cmcdData, targetSettings) { try { - if (isCmcdEnabled()) { - const cmcdData = getCmcdData(request); - const filteredCmcdData = _applyWhitelist(cmcdData); + if (targetSettings ? targetSettings.enabled : isCmcdEnabled()) { + + cmcdData = cmcdData || getCmcdData(request); + let [enabledKeys, customKeys] = _getTargetSettingsEnabledKeys(targetSettings, cmcdData); + + let filteredCmcdData = _applyWhitelist(cmcdData, enabledKeys); + filteredCmcdData = {...filteredCmcdData, ...customKeys}; const finalPayloadString = encodeCmcd(filteredCmcdData); eventBus.trigger(MetricsReportingEvents.CMCD_DATA_GENERATED, { url: request.url, mediaType: request.mediaType, + requestType: request.type, cmcdData, cmcdString: finalPayloadString }); @@ -192,17 +282,26 @@ function CmcdModel() { value: finalPayloadString }; } - + return null; } catch (e) { return null; } } - function _applyWhitelist(cmcdData) { + function includeEventModeMandatoryKeys(enabledCMCDKeys) { + + return enabledCMCDKeys.concat(Constants.CMCD_MANDATORY_KEYS); + } + + function _applyWhitelist(cmcdData, enabledKeys) { try { const cmcdParametersFromManifest = getCmcdParametersFromManifest(); - const enabledCMCDKeys = cmcdParametersFromManifest.version ? cmcdParametersFromManifest.keys : settings.get().streaming.cmcd.enabledKeys; + let enabledCMCDKeys = enabledKeys || (cmcdParametersFromManifest.version ? cmcdParametersFromManifest.keys : settings.get().streaming.cmcd.enabledKeys); + + if (cmcdData.e) { + enabledCMCDKeys = includeEventModeMandatoryKeys(enabledCMCDKeys) + } return Object.keys(cmcdData) .filter(key => enabledCMCDKeys.includes(key)) @@ -215,11 +314,16 @@ function CmcdModel() { } } - function getHeaderParameters(request) { + function getHeaderParameters(request, cmcdData, targetSettings) { try { if (isCmcdEnabled()) { - const cmcdData = getCmcdData(request); - const filteredCmcdData = _applyWhitelist(cmcdData); + cmcdData = cmcdData || getCmcdData(request); + + let [enabledKeys, customKeys] = _getTargetSettingsEnabledKeys(targetSettings, cmcdData); + + let filteredCmcdData = _applyWhitelist(cmcdData, enabledKeys); + filteredCmcdData = {...filteredCmcdData, ...customKeys}; + const options = _createCmcdV2HeadersCustomMap(); const headers = toCmcdHeaders(filteredCmcdData, options); @@ -285,6 +389,7 @@ function CmcdModel() { const defaultAvailableKeys = Constants.CMCD_AVAILABLE_KEYS; const defaultV2AvailableKeys = Constants.CMCD_V2_AVAILABLE_KEYS; const enabledCMCDKeys = cmcdParametersFromManifest.version ? cmcdParametersFromManifest.keys : settings.get().streaming.cmcd.enabledKeys; + const cmcdVersion = settings.get().streaming.cmcd.version; const invalidKeys = enabledCMCDKeys.filter(k => !defaultAvailableKeys.includes(k) && !(cmcdVersion === 2 && defaultV2AvailableKeys.includes(k))); @@ -314,9 +419,9 @@ function CmcdModel() { return cmcdParametersFromManifest; } - function _isIncludedInRequestFilter(type) { + function _isIncludedInRequestFilter(type, includeInRequests) { const cmcdParametersFromManifest = getCmcdParametersFromManifest(); - let includeInRequestsArray = settings.get().streaming.cmcd.includeInRequests; + let includeInRequestsArray = includeInRequests || settings.get().streaming.cmcd.includeInRequests; if (cmcdParametersFromManifest.version) { includeInRequestsArray = cmcdParametersFromManifest.includeInRequests ? cmcdParametersFromManifest.includeInRequests : [DEFAULT_INCLUDE_IN_REQUESTS]; @@ -532,6 +637,8 @@ function CmcdModel() { data.sid = `${data.sid}`; + data.ts = Date.now(); + if (cid) { data.cid = `${cid}`; } @@ -560,8 +667,6 @@ function CmcdModel() { } } - - return data; } @@ -677,7 +782,15 @@ function CmcdModel() { } } + function _onPlaybackSeeking() { + _isSeeking = true; + + _onStateChange(Constants.CMCD_REPORTING_EVENTS.PLAYBACK_SEEKING); + } + function _onPlaybackSeeked() { + _isSeeking = false; + for (let key in _bufferLevelStarved) { if (_bufferLevelStarved.hasOwnProperty(key)) { _bufferLevelStarved[key] = true; @@ -691,6 +804,14 @@ function CmcdModel() { } } + function _onPlaybackWaiting() { + if (_isSeeking || !_playbackStartedTime) { + return; + } + + _onStateChange(Constants.CMCD_REPORTING_EVENTS.REBUFFERING); + } + function _probeNextRequest(mediaType) { if (!streamProcessors || streamProcessors.length === 0) { return; @@ -735,6 +856,156 @@ function CmcdModel() { } } + function getCmcdRequestInterceptors() { + // Add here request interceptors + return [_cmcdRequestModeInterceptor]; + } + + function _cmcdRequestModeInterceptor(commonMediaRequest){ + const requestType = commonMediaRequest.customData.request.type; + + if (!_isIncludedInRequestFilter(requestType)) { + commonMediaRequest.cmcd = commonMediaRequest.customData.request.cmcd; + return commonMediaRequest; + } + + const request = commonMediaRequest.customData.request; + _updateRequestUrlAndHeadersWithCmcd(request, null, null); + + commonMediaRequest = { + ...commonMediaRequest, + url: request.url, + headers: request.headers, + customData: {request}, + cmcd: getCmcdData(request) + } + + return commonMediaRequest; + } + + /** + * Updates the request url and headers with CMCD data + * @param request + * @private + */ + function _updateRequestUrlAndHeadersWithCmcd(request, cmcdData, targetSettings) { + const currentServiceLocation = request?.serviceLocation; + const currentAdaptationSetId = request?.mediaInfo?.id?.toString(); + const isIncludedFilters = clientDataReportingController.isServiceLocationIncluded(request.type, currentServiceLocation) && + clientDataReportingController.isAdaptationsIncluded(currentAdaptationSetId); + + if (isIncludedFilters && (targetSettings ? targetSettings.enabled : isCmcdEnabled())) { + const cmcdParameters = getCmcdParametersFromManifest(); + const cmcdMode = cmcdParameters.mode ? cmcdParameters.mode : settings.get().streaming.cmcd.mode; + if (cmcdMode === Constants.CMCD_MODE_QUERY) { + request.url = Utils.removeQueryParameterFromUrl(request.url, Constants.CMCD_QUERY_KEY); + const additionalQueryParameter = _getAdditionalQueryParameter(request, cmcdData, targetSettings); + request.url = Utils.addAdditionalQueryParameterToUrl(request.url, additionalQueryParameter); + } else if (cmcdMode === Constants.CMCD_MODE_HEADER) { + request.headers = request.headers || {}; + request.headers = Object.assign(request.headers, getHeaderParameters(request, cmcdData, targetSettings)); + } + } + } + + /** + * Generates the additional query parameters to be appended to the request url + * @param {object} request + * @return {array} + * @private + */ + function _getAdditionalQueryParameter(request, cmcdData, targetSettings) { + try { + const additionalQueryParameter = []; + const cmcdQueryParameter = getQueryParameter(request, cmcdData, targetSettings); + + if (cmcdQueryParameter) { + additionalQueryParameter.push(cmcdQueryParameter); + } + + return additionalQueryParameter; + } catch (e) { + return []; + } + } + + function getCmcdResponseInterceptors(){ + return [_cmcdResponseModeInterceptor]; + } + + function _cmcdResponseModeInterceptor(response){ + const requestType = response.request.customData.request.type; + let cmcdData = response.request.cmcd; + cmcdData = _addCmcdResponseModeData(response, cmcdData); + const targets = settings.get().streaming.cmcd.targets + const responseModeTargets = targets.filter((target) => target.cmcdMode === Constants.CMCD_MODE.RESPONSE); + responseModeTargets.forEach(targetSettings => { + if (targetSettings.enabled && _isIncludedInRequestFilter(requestType, targetSettings.includeOnRequests)){ + let httpRequest = new CmcdReportRequest(); + httpRequest.url = targetSettings.url; + httpRequest.type = HTTPRequest.CMCD_RESPONSE; + httpRequest.method = HTTPRequest.GET; + + _updateRequestUrlAndHeadersWithCmcd(httpRequest, cmcdData, targetSettings) + _sendCmcdDataReport(httpRequest); + } + }); + return response; + } + + function _sendCmcdDataReport(request){ + urlLoader = URLLoader(context).create({ + errHandler: errHandler, + dashMetrics: dashMetrics, + mediaPlayerModel: mediaPlayerModel, + errors: Errors, + }); + + urlLoader.load({request}) + } + + function _addCmcdResponseModeData(response, cmcdData){ + const responseModeData = {}; + const requestType = response.request.customData.request.type; + + if (requestType === HTTPRequest.MEDIA_SEGMENT_TYPE){ + responseModeData.rc = response.status; + } + + return {...cmcdData, ...responseModeData} + } + + function _getCustomKeysValues(customKeysObj, currentKeys){ + const result = {}; + if (!customKeysObj || typeof customKeysObj !== 'object') { + return result; + } + + for (const key in customKeysObj) { + if (typeof customKeysObj[key] === 'function') { + result[key] = customKeysObj[key](currentKeys); + } + } + return result; + } + + function _getTargetSettingsEnabledKeys(targetSettings, cmcdData) { + let enabledKeys; + let customKeys + + if (targetSettings) { + enabledKeys = targetSettings.enabledKeys; + + if (enabledKeys == null) { + enabledKeys = Constants.CMCD_AVAILABLE_KEYS.concat(Constants.CMCD_V2_AVAILABLE_KEYS); + } + + customKeys = _getCustomKeysValues(targetSettings.customKeys, cmcdData); + } + + return [enabledKeys, customKeys]; + } + function reset() { eventBus.off(MediaPlayerEvents.PLAYBACK_RATE_CHANGED, _onPlaybackRateChanged, this); eventBus.off(MediaPlayerEvents.MANIFEST_LOADED, _onManifestLoaded, this); @@ -743,6 +1014,9 @@ function CmcdModel() { eventBus.off(MediaPlayerEvents.PLAYBACK_STARTED, _onPlaybackStarted, instance); eventBus.off(MediaPlayerEvents.PLAYBACK_PLAYING, _onPlaybackPlaying, instance); + eventBus.off(MediaPlayerEvents.PLAYBACK_SEEKING, _onPlaybackSeeking, instance); + eventBus.off(MediaPlayerEvents.PLAYBACK_WAITING, _onPlaybackWaiting, instance); + _resetInitialSettings(); } @@ -751,6 +1025,8 @@ function CmcdModel() { getQueryParameter, getHeaderParameters, getCmcdParametersFromManifest, + getCmcdRequestInterceptors, + getCmcdResponseInterceptors, setConfig, reset, initialize, @@ -762,5 +1038,5 @@ function CmcdModel() { return instance; } -CmcdModel.__dashjs_factory_name = 'CmcdModel'; -export default FactoryMaker.getSingletonFactory(CmcdModel); +CmcdController.__dashjs_factory_name = 'CmcdController'; +export default FactoryMaker.getSingletonFactory(CmcdController); diff --git a/src/streaming/models/CustomParametersModel.js b/src/streaming/models/CustomParametersModel.js index 6c3526f0cb..f98933c42b 100644 --- a/src/streaming/models/CustomParametersModel.js +++ b/src/streaming/models/CustomParametersModel.js @@ -33,6 +33,7 @@ import FactoryMaker from '../../core/FactoryMaker.js'; import Settings from '../../core/Settings.js'; import {checkParameterType} from '../utils/SupervisorTools.js'; import Constants from '../constants/Constants.js'; +import CmcdController from '../controllers/CmcdController.js'; const DEFAULT_XHR_WITH_CREDENTIALS = false; @@ -47,7 +48,8 @@ function CustomParametersModel() { licenseResponseFilters, customCapabilitiesFilters, customInitialTrackSelectionFunction, - customAbrRules; + customAbrRules, + cmcdController; const context = this.context; const settings = Settings(context).getInstance(); @@ -60,14 +62,17 @@ function CustomParametersModel() { } function _resetInitialSettings() { - requestInterceptors = []; - responseInterceptors = []; licenseRequestFilters = []; licenseResponseFilters = []; customCapabilitiesFilters = []; customAbrRules = []; customInitialTrackSelectionFunction = null; utcTimingSources = []; + + // Initialize request interceptors with default CMCD interceptors + cmcdController = CmcdController(context).getInstance(); + requestInterceptors = cmcdController.getCmcdRequestInterceptors(); + responseInterceptors = cmcdController.getCmcdResponseInterceptors(); } diff --git a/src/streaming/net/HTTPLoader.js b/src/streaming/net/HTTPLoader.js index 6b613666e6..c8f84cc173 100644 --- a/src/streaming/net/HTTPLoader.js +++ b/src/streaming/net/HTTPLoader.js @@ -33,7 +33,6 @@ import FetchLoader from './FetchLoader.js'; import {HTTPRequest} from '../vo/metrics/HTTPRequest.js'; import FactoryMaker from '../../core/FactoryMaker.js'; import DashJSError from '../vo/DashJSError.js'; -import CmcdModel from '../models/CmcdModel.js'; import CmsdModel from '../models/CmsdModel.js'; import Utils from '../../core/Utils.js'; import Debug from '../../core/Debug.js'; @@ -43,7 +42,6 @@ import Settings from '../../core/Settings.js'; import Constants from '../constants/Constants.js'; import CustomParametersModel from '../models/CustomParametersModel.js'; import CommonAccessTokenController from '../controllers/CommonAccessTokenController.js'; -import ClientDataReportingController from '../controllers/ClientDataReportingController.js'; import ExtUrlQueryInfoController from '../controllers/ExtUrlQueryInfoController.js'; import CommonMediaRequest from '../vo/CommonMediaRequest.js'; import CommonMediaResponse from '../vo/CommonMediaResponse.js'; @@ -73,13 +71,11 @@ function HTTPLoader(cfg) { delayedRequests, retryRequests, downloadErrorToRequestTypeMap, - cmcdModel, cmsdModel, xhrLoader, fetchLoader, customParametersModel, commonAccessTokenController, - clientDataReportingController, extUrlQueryInfoController, logger; @@ -88,8 +84,6 @@ function HTTPLoader(cfg) { httpRequests = []; delayedRequests = []; retryRequests = []; - cmcdModel = CmcdModel(context).getInstance(); - clientDataReportingController = ClientDataReportingController(context).getInstance(); cmsdModel = CmsdModel(context).getInstance(); customParametersModel = CustomParametersModel(context).getInstance(); commonAccessTokenController = CommonAccessTokenController(context).getInstance(); @@ -314,7 +308,7 @@ function HTTPLoader(cfg) { return new Promise((resolve) => { _applyRequestInterceptors(httpRequest).then((_httpRequest) => { httpRequest = _httpRequest; - + httpResponse.request = httpRequest; httpRequest.customData.onloadend = _onloadend; httpRequest.customData.onprogress = _onprogress; httpRequest.customData.onabort = _onabort; @@ -392,8 +386,8 @@ function HTTPLoader(cfg) { const loaderInformation = _getLoader(requestObject); const loader = loaderInformation.loader; requestObject.fileLoaderType = loaderInformation.fileLoaderType; - - requestObject.headers = {}; + + requestObject.headers = requestObject.headers || {}; _updateRequestUrlAndHeaders(requestObject); if (requestObject.range) { requestObject.headers['Range'] = 'bytes=' + requestObject.range; @@ -408,7 +402,6 @@ function HTTPLoader(cfg) { headers: requestObject.headers, credentials: withCredentials ? 'include' : 'omit', timeout: requestTimeout, - cmcd: cmcdModel.getCmcdData(requestObject), customData: { request: requestObject } }); @@ -584,7 +577,6 @@ function HTTPLoader(cfg) { * @private */ function _updateRequestUrlAndHeaders(request) { - _updateRequestUrlAndHeadersWithCmcd(request); if (request.retryAttempts === 0) { _addExtUrlQueryParameters(request); } @@ -620,51 +612,6 @@ function HTTPLoader(cfg) { } } - /** - * Updates the request url and headers with CMCD data - * @param request - * @private - */ - function _updateRequestUrlAndHeadersWithCmcd(request) { - const currentServiceLocation = request?.serviceLocation; - const currentAdaptationSetId = request?.mediaInfo?.id?.toString(); - const isIncludedFilters = clientDataReportingController.isServiceLocationIncluded(request.type, currentServiceLocation) && - clientDataReportingController.isAdaptationsIncluded(currentAdaptationSetId); - - if (isIncludedFilters && cmcdModel.isCmcdEnabled()) { - const cmcdParameters = cmcdModel.getCmcdParametersFromManifest(); - const cmcdMode = cmcdParameters.mode ? cmcdParameters.mode : settings.get().streaming.cmcd.mode; - if (cmcdMode === Constants.CMCD_MODE_QUERY) { - request.url = Utils.removeQueryParameterFromUrl(request.url, Constants.CMCD_QUERY_KEY); - const additionalQueryParameter = _getAdditionalQueryParameter(request); - request.url = Utils.addAdditionalQueryParameterToUrl(request.url, additionalQueryParameter); - } else if (cmcdMode === Constants.CMCD_MODE_HEADER) { - request.headers = Object.assign(request.headers, cmcdModel.getHeaderParameters(request)); - } - } - } - - /** - * Generates the additional query parameters to be appended to the request url - * @param {object} request - * @return {array} - * @private - */ - function _getAdditionalQueryParameter(request) { - try { - const additionalQueryParameter = []; - const cmcdQueryParameter = cmcdModel.getQueryParameter(request); - - if (cmcdQueryParameter) { - additionalQueryParameter.push(cmcdQueryParameter); - } - - return additionalQueryParameter; - } catch (e) { - return []; - } - } - /** * Aborts any inflight downloads * @memberof module:HTTPLoader diff --git a/src/streaming/protection/Protection.js b/src/streaming/protection/Protection.js index a1300ee0d4..a79dd169e9 100644 --- a/src/streaming/protection/Protection.js +++ b/src/streaming/protection/Protection.js @@ -124,7 +124,7 @@ function Protection() { if (protectionModel) { controller = ProtectionController(context).create({ BASE64: config.BASE64, - cmcdModel: config.cmcdModel, + cmcdController: config.cmcdController, constants: config.constants, customParametersModel: config.customParametersModel, debug: config.debug, diff --git a/src/streaming/protection/controllers/ProtectionController.js b/src/streaming/protection/controllers/ProtectionController.js index 6b41855272..b965755f56 100644 --- a/src/streaming/protection/controllers/ProtectionController.js +++ b/src/streaming/protection/controllers/ProtectionController.js @@ -68,7 +68,7 @@ function ProtectionController(config) { config = config || {}; const BASE64 = config.BASE64; - const cmcdModel = config.cmcdModel; + const cmcdController = config.cmcdController; const constants = config.constants; const customParametersModel = config.customParametersModel; const debug = config.debug; @@ -827,12 +827,12 @@ function ProtectionController(config) { */ function _doLicenseRequest(request, retriesCount, timeout, onLoad, onAbort, onError) { const xhr = new XMLHttpRequest(); - const cmcdParameters = cmcdModel.getCmcdParametersFromManifest(); + const cmcdParameters = cmcdController.getCmcdParametersFromManifest(); - if (cmcdModel.isCmcdEnabled()) { + if (cmcdController.isCmcdEnabled()) { const cmcdMode = cmcdParameters.mode ? cmcdParameters.mode : settings.get().streaming.cmcd.mode; if (cmcdMode === Constants.CMCD_MODE_QUERY) { - const cmcdParams = cmcdModel.getQueryParameter({ + const cmcdParams = cmcdController.getQueryParameter({ url: request.url, type: HTTPRequest.LICENSE }); @@ -853,10 +853,10 @@ function ProtectionController(config) { xhr.setRequestHeader(key, request.headers[key]); } - if (cmcdModel.isCmcdEnabled()) { + if (cmcdController.isCmcdEnabled()) { const cmcdMode = cmcdParameters.mode ? cmcdParameters.mode : settings.get().streaming.cmcd.mode; if (cmcdMode === Constants.CMCD_MODE_HEADER) { - const cmcdHeaders = cmcdModel.getHeaderParameters({ + const cmcdHeaders = cmcdController.getHeaderParameters({ url: request.url, type: HTTPRequest.LICENSE }); diff --git a/src/streaming/vo/CmcdReportRequest.js b/src/streaming/vo/CmcdReportRequest.js new file mode 100644 index 0000000000..a9b257faf4 --- /dev/null +++ b/src/streaming/vo/CmcdReportRequest.js @@ -0,0 +1,46 @@ +/** + * The copyright in this software is being made available under the BSD License, + * included below. This software may be subject to other third party and contributor + * rights, including patent rights, and no such rights are granted under this license. + * + * Copyright (c) 2013, Dash Industry Forum. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * Neither the name of Dash Industry Forum nor the names of its + * contributors may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @class + * @ignore + */ +import FragmentRequest from './FragmentRequest.js'; + +class CmcdReportRequest extends FragmentRequest { + constructor(url, type, method) { + super(); + this.url = url || null; + this.type = type || null; + this.method = method || null; + } +} + +export default CmcdReportRequest; diff --git a/src/streaming/vo/metrics/HTTPRequest.js b/src/streaming/vo/metrics/HTTPRequest.js index 55e2455e1d..46893d983f 100644 --- a/src/streaming/vo/metrics/HTTPRequest.js +++ b/src/streaming/vo/metrics/HTTPRequest.js @@ -53,6 +53,7 @@ class HTTPRequest { * - Index Fragment * - Media Fragment * - Bitstream Switching Fragment + * - CMCD Response * - other * @public */ @@ -178,6 +179,8 @@ HTTPRequest.MSS_FRAGMENT_INFO_SEGMENT_TYPE = 'FragmentInfoSegment'; HTTPRequest.DVB_REPORTING_TYPE = 'DVBReporting'; HTTPRequest.LICENSE = 'license'; HTTPRequest.CONTENT_STEERING_TYPE = 'ContentSteering'; +HTTPRequest.CMCD_RESPONSE = 'Response'; +HTTPRequest.CMCD_EVENT = 'Event'; HTTPRequest.OTHER_TYPE = 'other'; export {HTTPRequest, HTTPRequestTrace}; diff --git a/test/unit/test/streaming/streaming.models.CmcdModel.js b/test/unit/test/streaming/streaming.controllers.CmcdController.js similarity index 91% rename from test/unit/test/streaming/streaming.models.CmcdModel.js rename to test/unit/test/streaming/streaming.controllers.CmcdController.js index 1ab5327f47..6af91c165a 100644 --- a/test/unit/test/streaming/streaming.models.CmcdModel.js +++ b/test/unit/test/streaming/streaming.controllers.CmcdController.js @@ -1,4 +1,4 @@ -import CmcdModel from '../../../../src/streaming/models/CmcdModel.js'; +import CmcdController from '../../../../src/streaming/controllers/CmcdController.js'; import Settings from '../../../../src/core/Settings.js'; import {HTTPRequest} from '../../../../src/streaming/vo/metrics/HTTPRequest.js'; import EventBus from '../../../../src/core/EventBus.js'; @@ -22,8 +22,8 @@ const STATUS_HEADER_NAME = 'CMCD-Status'; const OBJECT_HEADER_NAME = 'CMCD-Object'; const REQUEST_HEADER_NAME = 'CMCD-Request'; -describe('CmcdModel', function () { - let cmcdModel; +describe('CmcdController', function () { + let cmcdController; let abrControllerMock; let dashMetricsMock = new DashMetricsMock(); @@ -35,21 +35,21 @@ describe('CmcdModel', function () { beforeEach(function () { abrControllerMock = new AbrControllerMock(); - cmcdModel = CmcdModel(context).getInstance(); - cmcdModel.initialize(); + cmcdController = CmcdController(context).getInstance(); + cmcdController.initialize(); settings.update({ streaming: { cmcd: { enabled: true, cid: null } } }); }); afterEach(function () { - cmcdModel.reset(); - cmcdModel = null; + cmcdController.reset(); + cmcdController = null; settings.reset(); serviceDescriptionControllerMock.reset(); }); describe('if configured', function () { beforeEach(function () { - cmcdModel.setConfig({ + cmcdController.setConfig({ abrController: abrControllerMock, dashMetrics: dashMetricsMock, playbackController: playbackControllerMock, @@ -77,7 +77,7 @@ describe('CmcdModel', function () { } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(SESSION_HEADER_NAME); expect(typeof headers[SESSION_HEADER_NAME]).to.equal('string'); expect(headers).to.have.property(OBJECT_HEADER_NAME); @@ -102,7 +102,7 @@ describe('CmcdModel', function () { mediaType: MEDIA_TYPE }; - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(SESSION_HEADER_NAME); expect(typeof headers[SESSION_HEADER_NAME]).to.equal('string'); expect(headers).to.have.property(OBJECT_HEADER_NAME); @@ -156,7 +156,7 @@ describe('CmcdModel', function () { url: 'http://test.url/firstRequest' }; - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(SESSION_HEADER_NAME); expect(typeof headers[SESSION_HEADER_NAME]).to.equal('string'); expect(headers).to.have.property(OBJECT_HEADER_NAME); @@ -196,7 +196,7 @@ describe('CmcdModel', function () { expect(metrics.rtp % 100).to.equal(0); request.url = 'http://test.url/next_object'; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[REQUEST_HEADER_NAME]); expect(metrics).to.have.property('nrr'); expect(metrics.nrr).to.equal(NEXT_OBJECT_RANGE); @@ -220,7 +220,7 @@ describe('CmcdModel', function () { } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(SESSION_HEADER_NAME); expect(typeof headers[SESSION_HEADER_NAME]).to.equal('string'); expect(headers).to.have.property(OBJECT_HEADER_NAME); @@ -248,13 +248,13 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); let metrics = decodeCmcd(headers[SESSION_HEADER_NAME]); expect(metrics).to.not.have.property('pr'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_RATE_CHANGED, { playbackRate: CHANGED_PLAYBACK_RATE }); - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[SESSION_HEADER_NAME]); expect(metrics).to.have.property('pr'); expect(metrics.pr).to.equal(CHANGED_PLAYBACK_RATE); @@ -273,8 +273,8 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - cmcdModel.getHeaderParameters(request); // first initial request will set startup to true - let headers = cmcdModel.getHeaderParameters(request); + cmcdController.getHeaderParameters(request); // first initial request will set startup to true + let headers = cmcdController.getHeaderParameters(request); let metrics = decodeCmcd(headers[STATUS_HEADER_NAME]); expect(metrics).to.not.have.property('bs'); metrics = decodeCmcd(headers[REQUEST_HEADER_NAME]); @@ -282,7 +282,7 @@ describe('CmcdModel', function () { eventBus.trigger(MediaPlayerEvents.PLAYBACK_SEEKED); - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[STATUS_HEADER_NAME]); expect(metrics).to.have.property('bs'); expect(metrics.bs).to.equal(true); @@ -304,8 +304,8 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - cmcdModel.getHeaderParameters(request); // first initial request will set startup to true - let headers = cmcdModel.getHeaderParameters(request); + cmcdController.getHeaderParameters(request); // first initial request will set startup to true + let headers = cmcdController.getHeaderParameters(request); let metrics = decodeCmcd(headers[STATUS_HEADER_NAME]); expect(metrics).to.not.have.property('bs'); metrics = decodeCmcd(headers[REQUEST_HEADER_NAME]); @@ -316,7 +316,7 @@ describe('CmcdModel', function () { mediaType: request.mediaType }); - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[STATUS_HEADER_NAME]); expect(metrics).to.have.property('bs'); expect(metrics.bs).to.equal(true); @@ -338,7 +338,7 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); let metrics = decodeCmcd(headers[SESSION_HEADER_NAME]); expect(metrics).to.not.have.property('st'); expect(metrics).to.not.have.property('sf'); @@ -348,7 +348,7 @@ describe('CmcdModel', function () { data: { type: DashConstants.DYNAMIC } }); - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[SESSION_HEADER_NAME]); expect(metrics).to.have.property('st'); expect(metrics.st).to.equal('l'); @@ -369,7 +369,7 @@ describe('CmcdModel', function () { settings.update({ streaming: { cmcd: { enabled: true, cid: CID, includeInRequests: ['mpd'] } } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(SESSION_HEADER_NAME); expect(typeof headers[SESSION_HEADER_NAME]).to.equal('string'); @@ -390,7 +390,7 @@ describe('CmcdModel', function () { settings.update({ streaming: { cmcd: { enabled: true, rtp: 10000 } } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(STATUS_HEADER_NAME); expect(typeof headers[STATUS_HEADER_NAME]).to.equal('string'); @@ -417,7 +417,7 @@ describe('CmcdModel', function () { } } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers[OBJECT_HEADER_NAME].split(',').map(e => { return e.split('=')[0] })).to.not.include('d'); @@ -445,7 +445,7 @@ describe('CmcdModel', function () { } } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers[OBJECT_HEADER_NAME]).to.be.undefined; expect(headers[REQUEST_HEADER_NAME]).to.be.undefined; expect(headers[STATUS_HEADER_NAME]).to.be.undefined; @@ -471,7 +471,7 @@ describe('CmcdModel', function () { } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.equals(null); }); @@ -484,7 +484,7 @@ describe('CmcdModel', function () { mediaType: MEDIA_TYPE }; - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -511,7 +511,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -539,7 +539,7 @@ describe('CmcdModel', function () { request = { type: MEDIA_SEMGENT_REQUEST_TYPE, }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -547,7 +547,7 @@ describe('CmcdModel', function () { request = { type: INIT_SEMGENT_REQUEST_TYPE, }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -555,7 +555,7 @@ describe('CmcdModel', function () { request = { type: XLINK_REQUEST_TYPE, }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -563,7 +563,7 @@ describe('CmcdModel', function () { request = { type: MDP_REQUEST_TYPE, }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -571,7 +571,7 @@ describe('CmcdModel', function () { request = { type: STEERING_REQUEST_TYPE, }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -596,7 +596,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers[OBJECT_HEADER_NAME]).to.be.undefined; expect(headers[REQUEST_HEADER_NAME]).to.be.undefined; expect(headers[STATUS_HEADER_NAME]).to.be.undefined; @@ -624,7 +624,7 @@ describe('CmcdModel', function () { type: MEDIA_SEGMENT_REQUEST_TYPE, mediaType: MEDIA_TYPE }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -633,7 +633,7 @@ describe('CmcdModel', function () { type: INIT_SGMENT_REQUEST_TYPE, mediaType: MEDIA_TYPE }; - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -659,7 +659,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); }); @@ -684,7 +684,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); }); @@ -708,7 +708,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); expect(headers).to.have.property(OBJECT_HEADER_NAME); expect(headers).to.have.property(REQUEST_HEADER_NAME); expect(headers).to.have.property(SESSION_HEADER_NAME); @@ -735,14 +735,14 @@ describe('CmcdModel', function () { } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); let metrics = decodeCmcd(headers[REQUEST_HEADER_NAME]); expect(metrics).to.have.property('ltc'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_STARTED); eventBus.trigger(MediaPlayerEvents.PLAYBACK_PLAYING); - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[SESSION_HEADER_NAME]); expect(metrics).to.have.property('msd'); }); @@ -766,14 +766,14 @@ describe('CmcdModel', function () { } }); - let headers = cmcdModel.getHeaderParameters(request); + let headers = cmcdController.getHeaderParameters(request); let metrics = decodeCmcd(headers[REQUEST_HEADER_NAME]); expect(metrics).to.not.have.property('ltc'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_STARTED); eventBus.trigger(MediaPlayerEvents.PLAYBACK_PLAYING); - headers = cmcdModel.getHeaderParameters(request); + headers = cmcdController.getHeaderParameters(request); metrics = decodeCmcd(headers[REQUEST_HEADER_NAME]); expect(metrics).to.not.have.property('msd'); }); @@ -801,7 +801,7 @@ describe('CmcdModel', function () { } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -824,7 +824,7 @@ describe('CmcdModel', function () { mediaType: MEDIA_TYPE }; - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -872,7 +872,7 @@ describe('CmcdModel', function () { url: 'http://test.url/firstRequest' }; - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -902,7 +902,7 @@ describe('CmcdModel', function () { expect(metrics.rtp % 100).to.equal(0); request.url = 'http://test.url/next_object'; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('nrr'); expect(metrics.nrr).to.equal(NEXT_OBJECT_RANGE); @@ -926,7 +926,7 @@ describe('CmcdModel', function () { } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -963,13 +963,13 @@ describe('CmcdModel', function () { }, duration: DURATION }; - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); let metrics = decodeCmcd(parameters.value); expect(metrics).to.not.have.property('pr'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_RATE_CHANGED, { playbackRate: CHANGED_PLAYBACK_RATE }); - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('pr'); expect(metrics.pr).to.equal(CHANGED_PLAYBACK_RATE); @@ -995,15 +995,15 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - cmcdModel.getQueryParameter(request); // first initial request will set startup to true - let parameters = cmcdModel.getQueryParameter(request); + cmcdController.getQueryParameter(request); // first initial request will set startup to true + let parameters = cmcdController.getQueryParameter(request); let metrics = decodeCmcd(parameters.value); expect(metrics).to.not.have.property('bs'); expect(metrics).to.not.have.property('su'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_SEEKED); - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('bs'); expect(metrics.bs).to.equal(true); @@ -1031,8 +1031,8 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - cmcdModel.getQueryParameter(request); // first initial request will set startup to true - let parameters = cmcdModel.getQueryParameter(request); + cmcdController.getQueryParameter(request); // first initial request will set startup to true + let parameters = cmcdController.getQueryParameter(request); let metrics = decodeCmcd(parameters.value); expect(metrics).to.not.have.property('bs'); expect(metrics).to.not.have.property('su'); @@ -1042,7 +1042,7 @@ describe('CmcdModel', function () { mediaType: request.mediaType }); - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('bs'); expect(metrics.bs).to.equal(true); @@ -1070,7 +1070,7 @@ describe('CmcdModel', function () { representation: { mediaInfo: { bitrateList: [{ bandwidth: BITRATE }] } }, duration: DURATION }; - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); let metrics = decodeCmcd(parameters.value); expect(metrics).to.not.have.property('st'); expect(metrics).to.not.have.property('sf'); @@ -1080,7 +1080,7 @@ describe('CmcdModel', function () { data: { type: DashConstants.DYNAMIC } }); - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('st'); expect(metrics.st).to.equal('l'); @@ -1101,7 +1101,7 @@ describe('CmcdModel', function () { settings.update({ streaming: { cmcd: { enabled: true, cid: CID, includeInRequests: ['mpd'] } } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -1129,7 +1129,7 @@ describe('CmcdModel', function () { settings.update({ streaming: { cmcd: { enabled: true, rtp: 10000 } } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -1158,7 +1158,7 @@ describe('CmcdModel', function () { } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -1189,7 +1189,7 @@ describe('CmcdModel', function () { } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters).to.have.property('value'); @@ -1218,7 +1218,7 @@ describe('CmcdModel', function () { } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.equals(null); }); @@ -1231,7 +1231,7 @@ describe('CmcdModel', function () { mediaType: MEDIA_TYPE }; - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.not.equal(null); @@ -1258,7 +1258,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); }); @@ -1285,35 +1285,35 @@ describe('CmcdModel', function () { request = { type: MEDIA_SEMGENT_REQUEST_TYPE, }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); request = { type: INIT_SEMGENT_REQUEST_TYPE, }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); request = { type: XLINK_REQUEST_TYPE, }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); request = { type: MDP_REQUEST_TYPE, }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); request = { type: STEERING_REQUEST_TYPE, }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); }); @@ -1336,7 +1336,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.be.empty; @@ -1364,7 +1364,7 @@ describe('CmcdModel', function () { type: MEDIA_SEGMENT_REQUEST_TYPE, mediaType: MEDIA_TYPE }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.not.equals(null); @@ -1373,7 +1373,7 @@ describe('CmcdModel', function () { type: INIT_SGMENT_REQUEST_TYPE, mediaType: MEDIA_TYPE }; - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.not.equals(null); @@ -1399,7 +1399,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.not.equals(null); @@ -1425,7 +1425,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.not.equals(null); @@ -1451,7 +1451,7 @@ describe('CmcdModel', function () { } serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.not.equals(null); @@ -1478,14 +1478,14 @@ describe('CmcdModel', function () { } } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); let metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('ltc'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_STARTED); eventBus.trigger(MediaPlayerEvents.PLAYBACK_PLAYING); - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.have.property('msd'); }); @@ -1509,14 +1509,14 @@ describe('CmcdModel', function () { } }); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); let metrics = decodeCmcd(parameters.value); expect(metrics).to.not.have.property('ltc'); eventBus.trigger(MediaPlayerEvents.PLAYBACK_STARTED); eventBus.trigger(MediaPlayerEvents.PLAYBACK_PLAYING); - parameters = cmcdModel.getQueryParameter(request); + parameters = cmcdController.getQueryParameter(request); metrics = decodeCmcd(parameters.value); expect(metrics).to.not.have.property('msd'); }); @@ -1555,7 +1555,7 @@ describe('CmcdModel', function () { }; serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.equal('cid="test-cid"'); @@ -1593,7 +1593,7 @@ describe('CmcdModel', function () { }; serviceDescriptionControllerMock.applyServiceDescription(serviceDescriptionSettings); - let parameters = cmcdModel.getQueryParameter(request); + let parameters = cmcdController.getQueryParameter(request); expect(parameters).to.have.property('key'); expect(parameters.key).to.equal('CMCD'); expect(parameters.value).to.equal('sid="sid-123"'); diff --git a/test/unit/test/streaming/streaming.net.HTTPLoader.js b/test/unit/test/streaming/streaming.net.HTTPLoader.js index 438d6e8631..73805be529 100644 --- a/test/unit/test/streaming/streaming.net.HTTPLoader.js +++ b/test/unit/test/streaming/streaming.net.HTTPLoader.js @@ -6,7 +6,7 @@ import MediaPlayerModelMock from '../../mocks/MediaPlayerModelMock.js'; import ServiceDescriptionControllerMock from '../../mocks/ServiceDescriptionControllerMock.js'; import {HTTPRequest} from '../../../../src/streaming/vo/metrics/HTTPRequest.js'; import Settings from '../../../../src/core/Settings.js'; -import CmcdModel from '../../../../src/streaming/models/CmcdModel.js'; +import CmcdController from '../../../../src/streaming/controllers/CmcdController.js'; import ClientDataReportingController from '../../../../src/streaming/controllers/ClientDataReportingController.js'; import {expect} from 'chai'; @@ -23,7 +23,7 @@ let settings = Settings(context).getInstance(); describe('HTTPLoader', function () { let serviceDescriptionControllerMock = new ServiceDescriptionControllerMock(); let clientDataReportingController, - cmcdModel; + cmcdController; beforeEach(function () { @@ -32,13 +32,13 @@ describe('HTTPLoader', function () { errHandler = ErrorHandler(context).getInstance(); dashMetrics = DashMetrics(context).getInstance(); clientDataReportingController = ClientDataReportingController(context).getInstance(); - cmcdModel = CmcdModel(context).getInstance(); + cmcdController = CmcdController(context).getInstance(); clientDataReportingController.setConfig({ serviceDescriptionController: serviceDescriptionControllerMock, }); - cmcdModel.setConfig({ + cmcdController.setConfig({ serviceDescriptionController: serviceDescriptionControllerMock, }); });