Skip to content

feat(CMCD): Add CMCD version 2 response mode #8781

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Changes from 1 commit
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
f97a544
[WIP] Split cmcd calcs for request and response mode
juanmanuel-qualabs May 27, 2025
e853442
Fixed response uri assignment
juanmanuel-qualabs May 28, 2025
3097df1
[WIP] Added basic code to use NetworkingEngine to send cmcd data for …
juanmanuel-qualabs May 28, 2025
df97d45
Sending CMCD data in response mode encoded as query parameters
juanmanuel-qualabs May 29, 2025
8ea7798
Added CmcdTarget object to allow configuring targets
juanmanuel-qualabs May 29, 2025
5e66783
Merge pull request #3 from qualabs/cmcdv2/response-mode
cotid-qualabs May 29, 2025
4b368b2
Fixed lintering issues
juanmanuel-qualabs May 30, 2025
c53d3ba
Merge branch 'main' into feature/cmcdv2
juanmanuel-qualabs May 30, 2025
336e768
Implemented PR improvements suggestions
juanmanuel-qualabs Jun 2, 2025
42b6aa1
Allowing includeKeys for each response target as well as request mode
juanmanuel-qualabs Jun 4, 2025
9948c12
Fixed lintering issues
juanmanuel-qualabs Jun 4, 2025
b6c14f1
Added response mode allowed keys and validation for these keys
juanmanuel-qualabs Jun 5, 2025
855cb8f
[WIP] Adding enabled/disabled config param for response mode only
juanmanuel-qualabs Jun 5, 2025
6124871
Fixed issue where disabling request mode disabled response mode as well
juanmanuel-qualabs Jun 6, 2025
c8a5248
Fixed lintering errors
juanmanuel-qualabs Jun 6, 2025
de5cdfc
Linter changes
juanmanuel-qualabs Jun 6, 2025
023fd64
[WIP] Allow "headers" for response mode
juanmanuel-qualabs Jun 6, 2025
6e0308a
Improved URL encoding on applyResponse method
juanmanuel-qualabs Jun 9, 2025
adfd830
Added msd sent tracking for response mode
juanmanuel-qualabs Jun 10, 2025
e0b3b84
Obtaining networkingEngine from playerInterface instead of instanciat…
juanmanuel-qualabs Jun 11, 2025
e964e0e
Fixed unit tests by adding getNetworkingEngine on playerInterface
juanmanuel-qualabs Jun 11, 2025
11ab1be
Fixed cmcd data being calculated once per target instead of being cal…
juanmanuel-qualabs Jun 12, 2025
bf771ef
Fixed NetworkingEngine initialization with CmcdManager
juanmanuel-qualabs Jun 12, 2025
828008c
[WIP] Adding Unit Tests for CMCD V2 Response & Request mode
juanmanuel-qualabs Jun 12, 2025
b8f5d05
Added sf unit test for response mode
juanmanuel-qualabs Jun 12, 2025
381c003
Update lib/util/cmcd_manager.js
juanmanuel-qualabs Jun 13, 2025
92d3508
Update lib/util/cmcd_manager.js
juanmanuel-qualabs Jun 13, 2025
62e8c4d
Remove whitespace from automatic commit
juanmanuel-qualabs Jun 13, 2025
fa63708
Moved CMCD dictionary definitions to a new CMCD section
juanmanuel-qualabs Jun 13, 2025
50615ef
Adding docs for shaka.extern.CmcdTarget
juanmanuel-qualabs Jun 13, 2025
8a4e9b3
Added V1 Key constant definition
juanmanuel-qualabs Jun 13, 2025
12556d1
Removed unnecesary <br>
juanmanuel-qualabs Jun 13, 2025
c1170ac
Added key filtering for request mode and cmcd v1
juanmanuel-qualabs Jun 13, 2025
c4581ff
Removed unnecessary logs and await
juanmanuel-qualabs Jun 13, 2025
28ef603
Fixed circular dependency in Unit Tests between playerInterface and c…
juanmanuel-qualabs Jun 18, 2025
ebfcf67
Fixed circular dependency in CMCD V2 Tests playerInterface and create…
juanmanuel-qualabs Jun 18, 2025
c7cf74e
Unified Create Networking Engine code for CMCD v1 and CMCD v2 unit tests
juanmanuel-qualabs Jun 18, 2025
23b3b3b
Fixed error due to missing NetworkingEngine type
juanmanuel-qualabs Jun 18, 2025
b800923
Fixed type error in spy
juanmanuel-qualabs Jun 18, 2025
53fdae6
Fixed media segment request tests
juanmanuel-qualabs Jun 18, 2025
faf3ed6
Fixed formatting
juanmanuel-qualabs Jun 18, 2025
866e615
Fixed type error in build due to tests
juanmanuel-qualabs Jun 18, 2025
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
Prev Previous commit
Next Next commit
Fixed circular dependency in Unit Tests between playerInterface and c…
…reateCmcdManager for CMCD V1 Tests
juanmanuel-qualabs committed Jun 18, 2025
commit 28ef603acb55a162bec48bc7af67d930d32e7129
126 changes: 78 additions & 48 deletions test/util/cmcd_manager_unit.js
Original file line number Diff line number Diff line change
@@ -41,12 +41,12 @@ describe('CmcdManager', () => {
{start: 35, end: 40},
],
}),
getNetworkingEngine: /** @return {shaka.net.NetworkingEngine} */ () => {
return createNetworkingEngine(createCmcdManager(createCmcdConfig()));
},
getNetworkingEngine: () => createNetworkingEngine(
createCmcdManager(playerInterface, createCmcdConfig()),
),
getCurrentTime: () => 10,
getPlaybackRate: () => 1,
getVariantTracks: () => /** @type {Array<shaka.extern.Track>} */([
getVariantTracks: () => /** @type {Array<shaka.extern.Track>} */ ([
{
type: 'variant',
bandwidth: 50000,
@@ -76,8 +76,8 @@ describe('CmcdManager', () => {
return Object.assign({}, config, cfg);
}

function createCmcdManager(cfg = {}) {
return new CmcdManager(playerInterface, createCmcdConfig(cfg));
function createCmcdManager(player, cfg = {}) {
return new CmcdManager(player, createCmcdConfig(cfg));
}

function createRequest() {
@@ -89,7 +89,7 @@ describe('CmcdManager', () => {
testing: '1234',
},
allowCrossSiteCredentials: false,
retryParameters: /** @type {shaka.extern.RetryParameters} */({}),
retryParameters: /** @type {shaka.extern.RetryParameters} */ ({}),
licenseRequestType: null,
sessionId: null,
drmInfo: null,
@@ -175,7 +175,7 @@ describe('CmcdManager', () => {
const ObjectUtils = shaka.util.ObjectUtils;

/** @type shaka.util.CmcdManager */
let cmcdManager = createCmcdManager();
let cmcdManager = createCmcdManager(playerInterface);

const createContext = (type) => {
return {
@@ -199,9 +199,12 @@ describe('CmcdManager', () => {

describe('configuration', () => {
it('does not modify requests when disabled', () => {
cmcdManager = createCmcdManager({
enabled: false,
});
cmcdManager = createCmcdManager(
playerInterface,
{
enabled: false,
},
);

const r = createRequest();
cmcdManager.applyManifestData(r, manifestInfo);
@@ -212,9 +215,12 @@ describe('CmcdManager', () => {
});

it('generates a session id if not provided', () => {
cmcdManager = createCmcdManager({
sessionId: '',
});
cmcdManager = createCmcdManager(
playerInterface,
{
sessionId: '',
},
);

const r = ObjectUtils.cloneObject(request);

@@ -224,7 +230,7 @@ describe('CmcdManager', () => {
});

it('generates a session id via configure', () => {
cmcdManager = createCmcdManager();
cmcdManager = createCmcdManager(playerInterface);

const r = createRequest();
cmcdManager.applyManifestData(r, manifestInfo);
@@ -248,9 +254,12 @@ describe('CmcdManager', () => {
});

it('filters keys if includeKeys is provided', () => {
cmcdManager = createCmcdManager({
includeKeys: ['sid', 'cid'],
});
cmcdManager = createCmcdManager(
playerInterface,
{
includeKeys: ['sid', 'cid'],
},
);

const r = createRequest();
cmcdManager.applyManifestData(r, manifestInfo);
@@ -263,7 +272,7 @@ describe('CmcdManager', () => {
describe('query mode', () => {
it('modifies all request uris', () => {
// modifies manifest request uris
cmcdManager = createCmcdManager();
cmcdManager = createCmcdManager(playerInterface);

let r = createRequest();
cmcdManager.applyManifestData(r, manifestInfo);
@@ -290,9 +299,12 @@ describe('CmcdManager', () => {

describe('header mode', () => {
it('modifies all request headers', () => {
cmcdManager = createCmcdManager({
useHeaders: true,
});
cmcdManager = createCmcdManager(
playerInterface,
{
useHeaders: true,
},
);

// modifies manifest request headers
let r = createRequest();
@@ -331,7 +343,7 @@ describe('CmcdManager', () => {

describe('src= mode', () => {
beforeEach(() => {
cmcdManager = createCmcdManager();
cmcdManager = createCmcdManager(playerInterface);
});

it('modifies media stream uris', () => {
@@ -363,9 +375,12 @@ describe('CmcdManager', () => {

describe('adheres to the spec', () => {
beforeEach(() => {
cmcdManager = createCmcdManager({
useHeaders: true,
});
cmcdManager = createCmcdManager(
playerInterface,
{
useHeaders: true,
},
);
cmcdManager.setBuffering(false);
cmcdManager.setBuffering(true);
});
@@ -401,7 +416,7 @@ describe('CmcdManager', () => {
const retry = NetworkingEngine.defaultRetryParameters();

beforeEach(() => {
cmcdManager = createCmcdManager();
cmcdManager = createCmcdManager(playerInterface);
networkingEngine = createNetworkingEngine(cmcdManager);
});

@@ -504,9 +519,12 @@ describe('CmcdManager', () => {
});

it('not when enabled is false', async () => {
cmcdManager = createCmcdManager({
enabled: false,
});
cmcdManager = createCmcdManager(
playerInterface,
{
enabled: false,
},
);
networkingEngine = createNetworkingEngine(cmcdManager);

const request = NetworkingEngine.makeRequest([uri], retry);
@@ -519,10 +537,13 @@ describe('CmcdManager', () => {
it('returns cmcd v2 data in query if version is 2', async () => {
// Set live to true to enable ltc
playerInterface.isLive = () => true;
cmcdManager = createCmcdManager({
version: 2,
includeKeys: ['ltc', 'msd', 'v'],
});
cmcdManager = createCmcdManager(
playerInterface,
{
version: 2,
includeKeys: ['ltc', 'msd', 'v'],
},
);
networkingEngine = createNetworkingEngine(cmcdManager);

// Trigger Play and Playing events
@@ -542,10 +563,13 @@ describe('CmcdManager', () => {
// Set live to true to enable ltc
playerInterface.isLive = () => true;

const cmcdManagerTmp = createCmcdManager({
version: 1,
includeKeys: ['ltc', 'msd'],
});
const cmcdManagerTmp = createCmcdManager(
playerInterface,
{
version: 1,
includeKeys: ['ltc', 'msd'],
},
);
networkingEngine = createNetworkingEngine(cmcdManagerTmp);

// Trigger Play and Playing events
@@ -562,11 +586,14 @@ describe('CmcdManager', () => {

it('returns cmcd v2 data in header if version is 2', async () => {
playerInterface.isLive = () => true;
cmcdManager = createCmcdManager({
version: 2,
includeKeys: ['ltc', 'msd'],
useHeaders: true,
});
cmcdManager = createCmcdManager(
playerInterface,
{
version: 2,
includeKeys: ['ltc', 'msd'],
useHeaders: true,
},
);
networkingEngine = createNetworkingEngine(cmcdManager);

// Trigger Play and Playing events
@@ -582,11 +609,14 @@ describe('CmcdManager', () => {
it('doesn\'t return cmcd v2 data in headers if version is not 2',
async () => {
playerInterface.isLive = () => true;
cmcdManager = createCmcdManager({
version: 1,
includeKeys: ['ltc', 'msd'],
useHeaders: true,
});
cmcdManager = createCmcdManager(
playerInterface,
{
version: 1,
includeKeys: ['ltc', 'msd'],
useHeaders: true,
},
);
networkingEngine = createNetworkingEngine(cmcdManager);
cmcdManager.onPlaybackPlay_();
cmcdManager.onPlaybackPlaying_();