feat(cmcd): upgrade to CMCD v2 using @svta/cml-cmcd CmcdReporter#7725
feat(cmcd): upgrade to CMCD v2 using @svta/cml-cmcd CmcdReporter#7725littlespex wants to merge 12 commits intovideo-dev:masterfrom
Conversation
…d v2 version support Replace the monolithic @svta/common-media-library package with the scoped @svta/cml-cmcd@2.1.0 and @svta/cml-utils@1.3.0 packages for CMCD functionality. The old package is retained for non-CMCD imports (ID3, UTF8). Add a `version` option to CMCDControllerConfig (defaults to 1 for backwards compatibility) that controls CMCD encoding version. When set to 2, the controller uses CMCD v2 Structured Field Value encoding via the new library. Key changes: - Update all CMCD imports to use @svta/cml-cmcd single entry point - Update uuid import to use @svta/cml-utils - Update tsconfig moduleResolution to "bundler" for exports field support - Adapt CMCD data fields (br, bl, mtp, tb, nor) to v2 array types - Pass version through to CmcdEncodeOptions for version-aware encoding https://claude.ai/code/session_01FmnN6xNSm9Qo17tp52ag3U
Phase 3: Add new CMCD v2 data fields to the controller: - Stream type (st): Detect VOD/LIVE/LOW_LATENCY from level details based on live flag, canBlockReload, and canSkipUntil properties - Player state (sta): Track player state transitions via media element events (waiting, playing, pause, seeking, ended) and hls.js ERROR events for fatal errors. Maps to CmcdPlayerState enum values. - Both fields are only included when version >= 2 Phase 4: Integrate CmcdReporter for event-mode reporting: - Add eventTargets config option (CmcdEventReportConfig[]) for v2 event reporting endpoints - Instantiate CmcdReporter when version >= 2 and eventTargets are configured, with session/content ID and transmission mode - Record PLAY_STATE events on player state transitions - Record ERROR events on fatal hls.js errors - Record BITRATE_CHANGE events on level switches - Stop and flush reporter on controller destroy Add unit tests for v2 version encoding, stream type detection (VOD, LIVE, LOW_LATENCY), and player state inclusion. https://claude.ai/code/session_01FmnN6xNSm9Qo17tp52ag3U
Phase 6: Re-export CMCD types and constants from exports-named.ts for ESM consumers: CmcdObjectType, CmcdStreamType, CmcdStreamingFormat, CmcdPlayerState, CmcdEventType, CmcdHeaderField, CMCD_V1, CMCD_V2, and type exports for Cmcd, CmcdEncodeOptions, CmcdEventReportConfig, CmcdVersion. Add @svta/cml-cmcd, @svta/cml-utils, and @svta/cml-structured-field-values to api-extractor bundledPackages so external types are inlined in the rolled-up dist/hls.d.ts. Phase 7: Add tests for: - v2 fragment data includes version, stream type, and player state - v2 headers mode includes v2 fields in CMCD headers - Reporter is not created without eventTargets or for v1 - Reporter is created with v2 + eventTargets - Reporter.stop(true) is called on destroy - Play state events are recorded on state transitions - Error events are recorded on fatal hls.js errors - Duplicate player state events are deduplicated Phase 8: Verified TypeScript type-check, all Rollup build configs (full, fullEsm, light), and api-extractor declaration bundling. https://claude.ai/code/session_01FmnN6xNSm9Qo17tp52ag3U
| // TODO: Is this the best way to determine the low-latency stream type? | ||
| if (details.canBlockReload || details.canSkipUntil) { | ||
| return CmcdStreamType.LOW_LATENCY; | ||
| } |
There was a problem hiding this comment.
@robwalch I'm not sure about this check. Is there a better way to determine if a stream is low latency?
| enabledKeys: cmcd.includeKeys ?? [ | ||
| ...(version >= CMCD_V2 ? CMCD_KEYS : CMCD_V1_KEYS), | ||
| ], |
There was a problem hiding this comment.
@cotid-qualabs, @dsilhavy, @nicolaslevy, @robwalch
An open question for both hls.js and dash.js: In CMCD version 1, all keys were enabled by default, and filtering keys via includeKeys/enabledKeys was opt-in. Version 2 introduces a number of new keys, and enabling them all by default would result in ~40 fields. To ensure backwards compatibility, we would at minimum need to enable all keys if the version property is 1. What should we do for version 2 reports? Enabling all keys would create large payloads, but not enabling then creates a more complicated use case for end users "If v1 you don't need to provide an allowed list, but if v2 you do".
Summary
Implements CMCD v2 support by migrating from
@svta/common-media-libraryto the dedicated@svta/cml-*packages and fully delegating CMCD encoding toCmcdReporterfrom@svta/cml-cmcd.Resolves #7723.
Changes
@svta/common-media-librarywith@svta/cml-cmcd,@svta/cml-id3,@svta/cml-utils, and@svta/cml-structured-field-valuesversion,st(stream type),sta(player state),sn(sequence number) to CMCD output. Inner list encoding forbr,tb,bl,mtp,norper v2 specCmcdReporter.createRequestReport(), removing manualappendCmcdHeaders/appendCmcdQuerycalls and thecreateData()methodPLAY_STATE), fatal errors (ERROR), and bitrate changes (BITRATE_CHANGE)version,enabledKeys, andeventTargetstoCMCDControllerConfig. DefaultenabledKeystoCMCD_V1_KEYS(v1) orCMCD_KEYS(v2)CmcdVersion,CmcdPlayerState,CmcdStreamType, etc.) fromexports-named.tsBehavioral notes
v=1is omitted from output per CMCD spec (it is the default)sn(sequence number) is automatically included in v2 output, filtered out for v1noruses root-relative paths (viaurl.originas baseUrl) instead of path-relativebl,tb) are guarded againstNaNto prevent Structured Fields serialization errorsTest plan