Skip to content

PoC: SGAI alternative cmcd#157

Draft
cotid-qualabs wants to merge 345 commits intodevelopmentfrom
sgai/alternative-cmcd
Draft

PoC: SGAI alternative cmcd#157
cotid-qualabs wants to merge 345 commits intodevelopmentfrom
sgai/alternative-cmcd

Conversation

@cotid-qualabs
Copy link

Alternative MPD and List MPD implementation with CMCDv2 integration

cotid-qualabs and others added 30 commits February 26, 2025 11:54
Co-authored-by: Sebastian Piquerez <89274285+sebastianpiq@users.noreply.github.com>
[MPDList] Add sample page for List MPDs
[MPDList] Fix MPD Lists BaseURI issues
…ds-bug

[MPDList] Fix handling of periods with duration but without start time
…eOffset-default

[AlternativeMPD] Add default (60 seconds) to the erliestResolutionTimeOffset
* Fix bug with the period duration precedense

* Don't update duration if the manifest have a media presentation duration
cotid-qualabs and others added 16 commits January 16, 2026 10:03
* feat: implement CMCD v2 functionality

* remove unused function

* Update src/dash/vo/EventTarget.js

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* cmcdvs parameters unit test

* fix unit tests

* add batch config from mpd

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@cotid-qualabs cotid-qualabs changed the title Sgai: alternative cmcd PoC: SGAI alternative cmcd Jan 29, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @cotid-qualabs, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the player's capabilities by integrating advanced DASH features such as CMCDv2, Alternative MPD events, and List MPDs. These additions provide greater flexibility for content providers to dynamically manage and report on media playback, enabling use cases like server-side ad insertion and seamless content transitions. The changes involve substantial refactoring of internal components to support these new functionalities, ensuring a more modular and maintainable codebase.

Highlights

  • CMCDv2 Integration: Implemented comprehensive support for Common Media Client Data version 2 (CMCDv2), including new configuration options, event-driven reporting, and network interceptors for custom data manipulation. This refactors CMCD logic into a dedicated controller and accessor for improved modularity and extensibility.
  • Alternative MPD Events: Introduced robust handling for Alternative MPD events (Replace and Insert modes) as defined in DASH, allowing dynamic content switching, prebuffering of alternative streams, and advanced control over playback transitions, including 'clip', 'executeOnce', 'noJump', and 'returnOffset' attributes.
  • List MPD Support: Added support for List MPDs, enabling dynamic manifest updates by loading external MPDs referenced within a main manifest's periods. This includes logic for merging manifests and handling period transitions based on earliest resolution times.
  • New Sample Pages: Added several new sample pages to demonstrate the new CMCDv2, Alternative MPD, and List MPD features, providing practical examples for developers.
  • Core Refactoring & Enhancements: Refactored core components like CmcdModel into a data-only model, introduced MediaManager for alternative video element control, and enhanced EventController and DashAdapter to support the new manifest features.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces significant enhancements across several core functionalities, primarily focusing on CMCD v2 support, List MPD implementation, and Alternative Media Presentations. Key changes include expanding the CmcdModel interface with new event handling methods and CMCD data retrieval functions, alongside adding new sample pages to demonstrate CMCD v2 reporting with network interceptors, List MPD use cases, and various Alternative Media Presentation scenarios (VOD, Live, Insert/Replace modes, executeOnce, clip, and returnOffset functionalities). Core logic updates involve modifying DashAdapter and DashManifestModel to handle merging and parsing of List MPDs and Alternative MPD events, introducing new Value Objects like AlternativeMpd and EventTarget, and updating Settings and CoreEvents to support these new features. The CMCD implementation has been refactored to use a CmcdConfigAccessor for unified configuration access and a CmcdBatchController for batched reporting, with corresponding updates to MediaPlayer, HTTPLoader, and ProtectionController to integrate these new CMCD mechanisms. Review comments highlighted the need for more specific TypeScript types in the CmcdModel interface, removal of redundant code, clarification of getKeysForJsonMode naming and implementation for CMCD body mode, correction of a JSDoc type for minEarliestResolutionTimeOffset, and a suggestion to relax a strict condition in mergeManifests regarding minBufferTime for period replacement.

Comment on lines +3766 to +3806
onStateChange(state: any): void;

getHeaderParameters(request: HTTPRequest): object | null;
onPeriodSwitchComplete(): void;

getQueryParameter(request: HTTPRequest): { key: string, finalPayloadString: string } | null;
onPlaybackStarted(): void;

initialize(): void;
onPlaybackPlaying(): void;

isCmcdEnabled(): boolean;
onRebufferingStarted(mediaType: string): void;

reset(): void;
onRebufferingCompleted(mediaType: string): void;

setConfig(config: object): void;
onPlayerError(errorData: any): void;

onPlaybackSeeking(): void;

onPlaybackSeeked(): void;

onPlaybackRateChanged(data: any): void;

wasPlaying(): boolean;

onManifestLoaded(data: any): void;

onBufferLevelStateChanged(data: any): void;

updateMsdData(mode: string): object;

resetInitialSettings(): void;

getCmcdParametersFromManifest(): CMCDParameters;

triggerCmcdEventMode(event: string): object;

getGenericCmcdData(mediaType?: string): object;

isIncludedInRequestFilter(type: string, includeInRequests?: any): boolean;

getLastMediaTypeRequest(): string;

onEventChange(state: any): void;

Choose a reason for hiding this comment

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

medium

Many of the new methods in the CmcdModel interface use any as a parameter type. While this works, it reduces the benefits of TypeScript's static type checking. Consider using more specific types where possible. For example:

  • onStateChange(state: string): void; (or an enum for states)
  • onPlayerError(errorData: DashJSError): void;
  • onPlaybackRateChanged(data: { playbackRate: number }): void;
  • onManifestLoaded(data: { manifest: object }): void;

This will improve type safety and make the API easier to use correctly.

<script>
function getKeysForQueryMode(cmcdString) {
var cmcdData = {};
var cmcdString = cmcdString;

Choose a reason for hiding this comment

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

medium

This line is redundant and has no effect. It can be safely removed.

Comment on lines +190 to +210
function getKeysForJsonMode(event){
const decoded = decodeURIComponent(event.cmcdString);
const entries = decoded.split(',');

const cmcdData = {};

for (let entry of entries) {
let [key, value] = entry.split('=');

if (value?.startsWith('"') && value.endsWith('"')) {
value = value.slice(1, -1);
}

if (!isNaN(value) && value.trim() !== '') {
value = Number(value);
}

cmcdData[key] = value;
}
return cmcdData;
}

Choose a reason for hiding this comment

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

medium

The function getKeysForJsonMode seems to be misnamed and its implementation might not align with the CMCD specification for body transmission mode. The CMCD specification states that when using HTTP POST (which body mode implies), the payload should be a JSON object. This function, however, parses a comma-separated key-value string, similar to query parameters.

If the event.cmcdString for body mode is indeed a JSON string, you should use JSON.parse(). If it's a custom format, the function should be renamed to avoid confusion (e.g., getKeysFromEncodedString). Please verify the format of event.cmcdString for CMCD_MODE_BODY and adjust accordingly.


/**
* @typedef {Object} listMpdSettings
* @property {boolean} [minEarliestResolutionTimeOffset=0]

Choose a reason for hiding this comment

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

medium

The JSDoc for minEarliestResolutionTimeOffset specifies the type as {boolean}, but the default value is 0 and its usage implies it's a number. The type should be {number}.

Suggested change
* @property {boolean} [minEarliestResolutionTimeOffset=0]
* @property {number} [minEarliestResolutionTimeOffset=0]

Comment on lines +415 to +419
if (newPeriod.minBufferTime && (newPeriod.AdaptationSet || newPeriod.duration === 0)) {
manifest.Period[periodIndex] = newPeriod;
} else {
manifest.Period.splice(periodIndex, 1);
}

Choose a reason for hiding this comment

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

medium

The condition for replacing or removing a period seems a bit strict. If newPeriod.minBufferTime is not present, the period will be removed from the manifest. Is this the intended behavior? It seems possible for a valid imported manifest to lack a top-level minBufferTime, which could lead to the period being unexpectedly removed. Consider relaxing this condition or adding a comment to explain why minBufferTime is a mandatory check here.

Comment on lines +1415 to +1416
alternativeMpd.clip = event.clip ? !(event.clip === 'false') : true;
alternativeMpd.startWithOffset = event.startWithOffset ? event.startWithOffset === 'true' : false;

Choose a reason for hiding this comment

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

medium

The boolean conversions for clip and startWithOffset can be simplified for better readability.

Suggested change
alternativeMpd.clip = event.clip ? !(event.clip === 'false') : true;
alternativeMpd.startWithOffset = event.startWithOffset ? event.startWithOffset === 'true' : false;
alternativeMpd.clip = event.clip !== 'false';
alternativeMpd.startWithOffset = event.startWithOffset === 'true';

cotid-qualabs and others added 11 commits February 2, 2026 15:07
* cmcd reporter initialization

* request mode migration

* event mode migration

* cmcd model migration

* fix cmcd model unit tests

* fixes for cmcd parameters and cleanup -
protection controller fixes WIP

* cleanup and update unit tests

* refactor unit tests and fixes

* fix unit tests and remove batchTimer
* ab, lab and tab inner list and request mode

* ab, tab and lab inner list for v2

* bl inner list and event mode

* br inner list and event mode

* toInnerList helper

* bsd inner list

* mtp inner list and event mode

* nor inner list

* pb inner list and event mode

* tp inner list and event mode

* tpb inner list and event mode

* fix unit tests
* chore: update CML dependencies

* fix: update common media request

* fix: update resourceTiming properties to use performance.now()

* fix: update cmcd data formatting

* fix: remove redundant rr values

* refactor: simplify cmcd reporting

* fix: test mock requests missing parameters

* chore: update cml cmcd version

* should not send report if events are undefined

* fix unit tests

---------

Co-authored-by: cotid-qualabs <constanzad@qualabs.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.