Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
},
"dependencies": {
"@svta/cml-608": "1.0.2",
"@svta/cml-cmcd": "2.3.2",
"@svta/cml-cmcd": "2.4.0",
"@svta/cml-cmsd": "1.0.6",
"@svta/cml-dash": "1.0.6",
"@svta/cml-id3": "1.0.6",
Expand Down
71 changes: 44 additions & 27 deletions src/streaming/controllers/CmcdController.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,35 @@ function CmcdController() {
});
}

function _onPlaybackStateChange(state) {
// Update CmcdReporter with the new player state
if (cmcdReporter) {
cmcdReporter.update({ sta: state });
function _partialHasStateField(partial) {
const stateFields = ['sta', 'pr', 'cid', 'bg', 'br'];
return stateFields.some((field) => field in partial);
}

function _updateCmcdReporter(partial = {}) {
if (!cmcdReporter) {
return;
}

_rebuildReporterIfNeeded();

const msdData = cmcdModel.calculateMsd();
const metrics = _partialHasStateField(partial)
? cmcdModel.getEventModeData()
: cmcdModel.getContinuousCmcdData();
const payload = {
...metrics,
...partial,
};
if (msdData.msd !== undefined) {
payload.msd = msdData.msd;
}
triggerCmcdEventMode(Constants.CMCD_REPORTING_EVENTS.PLAY_STATE);

cmcdReporter.update(payload);
}

function _onPlaybackStateChange(state) {
_updateCmcdReporter({ sta: state });
}

function _createCmcdReporter() {
Expand Down Expand Up @@ -250,15 +273,12 @@ function CmcdController() {
if (errorData.error?.data?.request?.type === HTTPRequest.CMCD_EVENT) {
return;
}
// Update CmcdReporter with the error code
if (cmcdReporter) {
const errorCode = errorData.error?.code || errorData.error?.data?.code;
if (errorCode) {
cmcdReporter.update({ ec: errorCode });
}
const errorCode = errorData.error?.code || errorData.error?.data?.code;
const eventData = cmcdModel.getEventModeData();
if (errorCode !== undefined) {
eventData.ec = Array.isArray(errorCode) ? errorCode : [String(errorCode)];
}

triggerCmcdEventMode(Constants.CMCD_REPORTING_EVENTS.ERROR);
triggerCmcdEventMode(Constants.CMCD_REPORTING_EVENTS.ERROR, eventData);
}

function _rebuildReporterIfNeeded() {
Expand Down Expand Up @@ -289,23 +309,23 @@ function CmcdController() {
* The handler that is triggered for CMCD event mode events (e.g., play, pause, error). Note that response recevived (rr) events are handled by getCmcdResponseReceivedInterceptors.
* @param event
*/
function triggerCmcdEventMode(event) {
function triggerCmcdEventMode(event, eventData) {
if (!cmcdReporter) {
return;
}

_rebuildReporterIfNeeded();

const cmcdData = cmcdModel.getEventModeData();

// Route media start delay (MSD) through update() for the reporter's internal send-once tracking
const msdData = cmcdModel.calculateMsd();
if (msdData.msd !== undefined) {
cmcdReporter.update(msdData);
}

// Pass event-mode data as transient per-event data (not persisted)
cmcdReporter.recordEvent(event, cmcdData);
const data = eventData !== undefined
? eventData
: cmcdModel.getEventModeData();

cmcdReporter.recordEvent(event, data);
}

/**
Expand All @@ -324,13 +344,9 @@ function CmcdController() {
_rebuildReporterIfNeeded();

try {
const cmcdData = cmcdModel.deriveCmcdDataForRequest(request);
_updateCmcdReporter();

// Route MSD through update() for the reporter's internal send-once tracking
const msdData = cmcdModel.calculateMsd();
if (msdData.msd !== undefined) {
cmcdReporter.update(msdData);
}
const cmcdData = cmcdModel.deriveCmcdDataForRequest(request);

const decorated = cmcdReporter.createRequestReport(request, cmcdData);
request.url = decorated.url;
Expand Down Expand Up @@ -457,9 +473,10 @@ function CmcdController() {

function _onPlaybackRateChanged(data) {
const prData = cmcdModel.onPlaybackRateChanged(data);
if (cmcdReporter && prData) {
cmcdReporter.update(prData);
if (!prData) {
return;
}
_updateCmcdReporter(prData);
}

function _onManifestLoaded(data) {
Expand Down
16 changes: 12 additions & 4 deletions src/streaming/models/CmcdModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,10 @@ function CmcdModel() {
function getGenericCmcdData(mediaType) {
const data = {};

// Note: ts, st, sf, pr are handled by CmcdReporter:
// - ts: auto-generated by recordEvent() / recordResponseReceived()
// - st, sf: persisted via cmcdReporter.update() in _onManifestLoaded
// - pr: persisted via cmcdReporter.update() in _onPlaybackRateChanged
// Note: ts is auto-generated by CmcdReporter recordEvent / recordResponseReceived.
// st, sf: persisted via cmcdReporter.update() on manifest load (CmcdController).
// sta, pr: persisted and state-change events fired via _updateCmcdReporter() in CmcdController.
// bl, mtp, ab, etc.: refreshed via _updateCmcdReporter() for TIME_INTERVAL and state transitions.

let ltc = playbackController.getCurrentLiveLatency() * 1000;
if (!isNaN(ltc)) {
Expand Down Expand Up @@ -601,6 +601,13 @@ function CmcdModel() {
return cmcdData;
}

function getContinuousCmcdData() {
const data = getEventModeData();
delete data.bg;
delete data.br;
return data;
}
Comment on lines +607 to +609

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in d22b82c: _getMetricsCmcdData() builds continuous snapshots without calling _getEncodedBitrateData() or setting bg, instead of computing those fields and deleting them on every applyCmcdToRequest refresh.



function resetInitialSettings() {
_bufferLevelStarved = {};
Expand Down Expand Up @@ -861,6 +868,7 @@ function CmcdModel() {
deriveCmcdDataForRequest,
getCmcdParametersFromManifest,
getEventModeData,
getContinuousCmcdData,
getLastMediaTypeRequest,
isIncludedInRequestFilter,
onBufferLevelStateChanged,
Expand Down
27 changes: 27 additions & 0 deletions test/functional/config/test-configurations/streams/cmcd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"testfiles": {
"included": [
"feature-support/cmcd",
"feature-support/cmcd-v2"
],
"excluded": []
},
"testvectors": [
{
"name": "DASH-IF Live Sim - Segment Template without manifest updates",
"type": "live",
"url": "https://livesim2.dashif.org/livesim2/testpic_2s/Manifest.mpd",
"includedTestfiles": [
"feature-support/cmcd"
]
},
{
"name": "BBB 30fps VoD CMCD v2",
"type": "vod",
"url": "https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd",
"includedTestfiles": [
"feature-support/cmcd-v2"
]
}
]
}
Loading
Loading