Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion src/core/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -912,8 +912,24 @@ import Events from './events/Events.js';
* The version of the CMCD to use.
*
* If not specified this value defaults to 1.
* @property {Array.<CmcdTarget>} [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 {Array.<string>} [enabledKeys]
* CMCD keys to include in the report.
* @property {Array.<string>} [includeOnRequests]
* Types of requests CMCD should be included on (e.g., 'mpd', 'segment').
*/

/**
* @typedef {Object} module:Settings~CmsdSettings
* @property {boolean} [enabled=false]
Expand Down Expand Up @@ -1361,7 +1377,8 @@ function Settings() {
mode: Constants.CMCD_MODE_QUERY,
enabledKeys: Constants.CMCD_AVAILABLE_KEYS,
includeInRequests: ['segment', 'mpd'],
version: 1
version: 1,
targets: []
},
cmsd: {
enabled: false,
Expand Down
10 changes: 10 additions & 0 deletions src/streaming/constants/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,16 @@ 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'
},

INITIALIZE: 'initialize',
TEXT_SHOWING: 'showing',
Expand Down
102 changes: 64 additions & 38 deletions src/streaming/controllers/CmcdController.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,6 @@ import Errors from '../../core/errors/Errors.js';
const DEFAULT_CMCD_VERSION = 1;
const DEFAULT_INCLUDE_IN_REQUESTS = 'segment';
const RTP_SAFETY_FACTOR = 5;
const ALLOWED_TYPES = [
HTTPRequest.MPD_TYPE,
HTTPRequest.INIT_SEGMENT_TYPE,
HTTPRequest.MEDIA_SEGMENT_TYPE,
HTTPRequest.OTHER_TYPE,
HTTPRequest.XLINK_EXPANSION_TYPE,
HTTPRequest.LICENSE,
HTTPRequest.CONTENT_STEERING_TYPE
];

function CmcdController() {

Expand Down Expand Up @@ -202,11 +193,20 @@ function CmcdController() {
streamProcessors = activeStream.getStreamProcessors();
}

function getQueryParameter(request, cmcdData) {
function getQueryParameter(request, cmcdData, targetSettings) {
try {
if (isCmcdEnabled()) {
cmcdData = cmcdData || getCmcdData(request);
const filteredCmcdData = _applyWhitelist(cmcdData);
let enabledKeys;
let customKeys;

if (targetSettings){
enabledKeys = targetSettings.enabledKeys;
customKeys = _getCustomKeysValues(targetSettings.customKeys, cmcdData);
}

let filteredCmcdData = _applyWhitelist(cmcdData, enabledKeys);
filteredCmcdData = {...filteredCmcdData, ...customKeys};
const finalPayloadString = encodeCmcd(filteredCmcdData);

eventBus.trigger(MetricsReportingEvents.CMCD_DATA_GENERATED, {
Expand All @@ -227,11 +227,10 @@ function CmcdController() {
}
}

function _applyWhitelist(cmcdData) {
function _applyWhitelist(cmcdData, enabledKeys) {
try {
const cmcdParametersFromManifest = getCmcdParametersFromManifest();
const enabledCMCDKeys = cmcdParametersFromManifest.version ? cmcdParametersFromManifest.keys : settings.get().streaming.cmcd.enabledKeys;

const enabledCMCDKeys = enabledKeys || (cmcdParametersFromManifest.version ? cmcdParametersFromManifest.keys : settings.get().streaming.cmcd.enabledKeys);
return Object.keys(cmcdData)
.filter(key => enabledCMCDKeys.includes(key))
.reduce((obj, key) => {
Expand All @@ -243,11 +242,21 @@ function CmcdController() {
}
}

function getHeaderParameters(request, cmcdData) {
function getHeaderParameters(request, cmcdData, targetSettings) {
try {
if (isCmcdEnabled()) {
cmcdData = cmcdData || getCmcdData(request);
const filteredCmcdData = _applyWhitelist(cmcdData);
let enabledKeys;
let customKeys;

if (targetSettings){
enabledKeys = targetSettings.enabledKeys;
customKeys = _getCustomKeysValues(targetSettings.customKeys, cmcdData);
}

let filteredCmcdData = _applyWhitelist(cmcdData, enabledKeys);
filteredCmcdData = {...filteredCmcdData, ...customKeys};

const options = _createCmcdV2HeadersCustomMap();
const headers = toCmcdHeaders(filteredCmcdData, options);

Expand Down Expand Up @@ -342,9 +351,9 @@ function CmcdController() {
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];
Expand Down Expand Up @@ -764,19 +773,19 @@ function CmcdController() {
}

function getCmcdRequestInterceptors() {
// Add here the futures request interceptors
// Add here request interceptors
return [_cmcdRequestModeInterceptor];
}

function _cmcdRequestModeInterceptor(commonMediaRequest){
const requestType = commonMediaRequest.customData.request.type;
if (!ALLOWED_TYPES.includes(requestType)) {

if (!_isIncludedInRequestFilter(requestType)) {
return commonMediaRequest;
}

const request = commonMediaRequest.customData.request;

_updateRequestUrlAndHeadersWithCmcd(request);
_updateRequestUrlAndHeadersWithCmcd(request, null, null);

commonMediaRequest = {
...commonMediaRequest,
Expand All @@ -794,7 +803,7 @@ function CmcdController() {
* @param request
* @private
*/
function _updateRequestUrlAndHeadersWithCmcd(request, cmcdData) {
function _updateRequestUrlAndHeadersWithCmcd(request, cmcdData, targetSettings) {
const currentServiceLocation = request?.serviceLocation;
const currentAdaptationSetId = request?.mediaInfo?.id?.toString();
const isIncludedFilters = clientDataReportingController.isServiceLocationIncluded(request.type, currentServiceLocation) &&
Expand All @@ -805,10 +814,10 @@ function CmcdController() {
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);
const additionalQueryParameter = _getAdditionalQueryParameter(request, cmcdData, targetSettings);
request.url = Utils.addAdditionalQueryParameterToUrl(request.url, additionalQueryParameter);
} else if (cmcdMode === Constants.CMCD_MODE_HEADER) {
request.headers = Object.assign(request.headers, getHeaderParameters(request));
request.headers = Object.assign(request.headers, getHeaderParameters(request, cmcdData, targetSettings));
}
}
}
Expand All @@ -819,10 +828,10 @@ function CmcdController() {
* @return {array}
* @private
*/
function _getAdditionalQueryParameter(request,cmcdData) {
function _getAdditionalQueryParameter(request, cmcdData, targetSettings) {
try {
const additionalQueryParameter = [];
const cmcdQueryParameter = getQueryParameter(request,cmcdData);
const cmcdQueryParameter = getQueryParameter(request, cmcdData, targetSettings);

if (cmcdQueryParameter) {
additionalQueryParameter.push(cmcdQueryParameter);
Expand All @@ -840,21 +849,24 @@ function CmcdController() {

function _cmcdResponseModeInterceptor(response){
const requestType = response.request.customData.type;
if (!ALLOWED_TYPES.includes(requestType)) {
return response;
}

let cmcdData = response.request.cmcd;
let params = {
url: 'http://example.com/report',
method: 'GET',
};

let httpRequest = new HttpLoaderRequest(params);
_updateRequestUrlAndHeadersWithCmcd(httpRequest, cmcdData)

_sendCmcdDataReport(httpRequest);
const targets = settings.get().streaming.cmcd.targets
const responseModeTargets = targets.filter((element) => element.mode = Constants.CMCD_MODE.RESPONSE);
responseModeTargets.forEach(element => {
if (element.enabled && _isIncludedInRequestFilter(requestType, element.includeOnRequests)){
let params = {
url: element.url,
method: 'GET',
};

let httpRequest = new HttpLoaderRequest(params);
const targetSettings = element;
_updateRequestUrlAndHeadersWithCmcd(httpRequest, cmcdData, targetSettings)
_sendCmcdDataReport(httpRequest);
}
});
return response;
}

Expand All @@ -869,6 +881,20 @@ function CmcdController() {
urlLoader.load({request})
}

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 reset() {
eventBus.off(MediaPlayerEvents.PLAYBACK_RATE_CHANGED, _onPlaybackRateChanged, this);
eventBus.off(MediaPlayerEvents.MANIFEST_LOADED, _onManifestLoaded, this);
Expand Down