Skip to content
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

Comscore Connector #8

Merged
merged 68 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
c2d7fd8
npm init
wjoosen Mar 17, 2024
3fb4401
add documentation
wjoosen Mar 17, 2024
21b7f31
start changelog
wjoosen Mar 17, 2024
bf41744
example test page
wjoosen Mar 17, 2024
fad6495
add theoplayer dependency
wjoosen Mar 17, 2024
b07f1b8
add api files and empty integration class
wjoosen Mar 17, 2024
60aa55c
add eventlisteners and playback states
wjoosen Mar 17, 2024
599fde1
initialize instance variables
wjoosen Mar 17, 2024
d442968
remove event listeners on destroy
wjoosen Mar 17, 2024
74d9ea6
add type declarations
wjoosen Mar 19, 2024
6c745a7
add NONE option to ContentDeliveryAdvertisementCapability
wjoosen Mar 20, 2024
d7800c0
prepare metadata setting functions
wjoosen Mar 20, 2024
3ff22c7
put mediaplayer name and version setter at correct level
wjoosen Mar 20, 2024
f87a23d
move metadata building to separate file
wjoosen Mar 20, 2024
08879f3
add logging for metadata setting
wjoosen Mar 20, 2024
839716e
add and clarify use of instance variables
wjoosen Mar 20, 2024
a678d24
add comment
wjoosen Mar 20, 2024
edabe7d
set and unset some fields used to build metadata objects
wjoosen Mar 20, 2024
82d9205
set relevant admetadata fields
wjoosen Mar 20, 2024
fef9931
set ad metadata on ad begin
wjoosen Mar 20, 2024
e565223
finish streamingAnalytics part
wjoosen Mar 21, 2024
fb019a2
finish first version
wjoosen Mar 21, 2024
2bf2e02
prepare build tooling
wjoosen Mar 22, 2024
648b85e
add comscore sdk documentation
wjoosen Mar 22, 2024
4b97381
fix calling set media player name and version from wrong interface
wjoosen Mar 22, 2024
bad865d
use any for Skeleton for now
wjoosen Mar 22, 2024
9936aa6
use variable content io name
wjoosen Mar 22, 2024
5da98fb
change to interface
wjoosen Mar 22, 2024
3ea7f36
refine logging
wjoosen Mar 22, 2024
aa7a77f
use const
wjoosen Mar 22, 2024
f2c87c1
correct type declaration
wjoosen Mar 22, 2024
d078887
use const
wjoosen Mar 22, 2024
464bda8
pass remaining arguments to ContentMetadata
wjoosen Mar 22, 2024
59b2b36
add index.ts
wjoosen Mar 22, 2024
9f12dde
extend test page
wjoosen Mar 22, 2024
bc5f66d
Prevent notifyEnd of main content coming through after mid-roll ad me…
wjoosen Mar 22, 2024
cb9fba9
check in test assets
wjoosen Mar 22, 2024
89a865c
prevent setting content metadata after post-roll
wjoosen Mar 22, 2024
14bb003
count restart after ended event as a new playback session
wjoosen Mar 22, 2024
861e88f
report main content metadata before setting DVR window length and off…
wjoosen Mar 25, 2024
ae9747f
don't handle loadedmetadata and playing events after a postroll adbre…
wjoosen Mar 25, 2024
71ff30d
don't report main content play before pre-roll and add notifyPlay for…
wjoosen Mar 25, 2024
7aa1c6b
detect Google DAI post rolls
wjoosen Mar 25, 2024
e7c1f1e
update google dai test stream
wjoosen Mar 25, 2024
72242c4
Update to THEOplayer 7.0
MattiasBuelens Apr 9, 2024
e3d2fe9
Add Comscore connector to workspace
MattiasBuelens Apr 9, 2024
9204b34
Update Rollup config
MattiasBuelens Apr 9, 2024
d912586
Add .gitignore
MattiasBuelens Apr 9, 2024
154f23f
Fix scripts
MattiasBuelens Apr 9, 2024
5112ea8
Fix tsconfig
MattiasBuelens Apr 9, 2024
8d5e61d
Set up TypeDoc
MattiasBuelens Apr 9, 2024
76af36e
Set up exports
MattiasBuelens Apr 9, 2024
ec10975
Fix repository and bugs fields
MattiasBuelens Apr 9, 2024
20fa4c3
Add basic README
MattiasBuelens Apr 9, 2024
784b03e
Fix JSDoc
MattiasBuelens Apr 9, 2024
64a31c0
Export all configuration and metadata types
MattiasBuelens Apr 9, 2024
4b6a343
Run Prettier
MattiasBuelens Apr 9, 2024
45e8917
fix serve script
wjoosen Apr 10, 2024
b9fe1b3
Add Comscore to available connectors in README
MattiasBuelens Apr 10, 2024
b591f08
add esm example
wjoosen Apr 11, 2024
2e5f70c
update README
wjoosen Apr 11, 2024
14e558c
add ComScore SDK loading insctructions to README
wjoosen Apr 11, 2024
eb4b49d
add warning for missing comscore.js in test pages
wjoosen Apr 11, 2024
391ae2b
remove docs
wjoosen Apr 11, 2024
049aa99
Revert to 1.0.20, will be bumped on next release
MattiasBuelens Apr 11, 2024
1f6f9a2
Add changeset
MattiasBuelens Apr 11, 2024
c71de9d
add reference to comscore page with documentation
wjoosen Apr 11, 2024
05e8db3
Add changeset for latest bugfix
wjoosen Apr 11, 2024
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
5 changes: 5 additions & 0 deletions .changeset/odd-scissors-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@theoplayer/comscore-connector-web": patch
---

Initial release to npm.
MattiasBuelens marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Using the available connectors allows you to augment the features delivered thro
| Connector | npm package | Source code |
|:----------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------|
| CMCD | [![@theoplayer/cmcd-connector-web](https://img.shields.io/npm/v/%40theoplayer%2Fcmcd-connector-web?label=%40theoplayer%2Fcmcd-connector-web)](https://npmjs.com/package/@theoplayer/cmcd-connector-web) | [cmcd](https://github.com/THEOplayer/web-connectors/tree/main/cmcd) |
| Comscore | [![@theoplayer/comscore-connector-web](https://img.shields.io/npm/v/%40theoplayer%2Fcomscore-connector-web?label=%40theoplayer%2Fcomscore-connector-web)](https://npmjs.com/package/@theoplayer/comscore-connector-web) | [comscore](https://github.com/THEOplayer/web-connectors/tree/main/comscore) |
| Conviva | [![@theoplayer/conviva-connector-web](https://img.shields.io/npm/v/%40theoplayer%2Fconviva-connector-web?label=%40theoplayer%2Fconviva-connector-web)](https://npmjs.com/package/@theoplayer/conviva-connector-web) | [conviva](https://github.com/THEOplayer/web-connectors/tree/main/conviva) |
| Nielsen | [![@theoplayer/nielsen-connector-web](https://img.shields.io/npm/v/%40theoplayer%2Fnielsen-connector-web?label=%40theoplayer%2Fnielsen-connector-web)](https://npmjs.com/package/@theoplayer/nielsen-connector-web) | [nielsen](https://github.com/THEOplayer/web-connectors/tree/main/nielsen) |
| Yospace | [![@theoplayer/yospace-connector-web](https://img.shields.io/npm/v/%40theoplayer%2Fyospace-connector-web?label=%40theoplayer%2Fyospace-connector-web)](https://npmjs.com/package/@theoplayer/yospace-connector-web) | [yospace](https://github.com/THEOplayer/web-connectors/tree/main/yospace) |
Expand Down
3 changes: 3 additions & 0 deletions cmcd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"url": "git+https://github.com/THEOplayer/web-connectors.git",
"directory": "cmcd"
},
"bugs": {
"url": "https://github.com/THEOplayer/web-connectors/issues"
},
"homepage": "https://theoplayer.com/",
"module": "dist/cmcd-connector.esm.js",
"types": "dist/types/index.d.ts",
Expand Down
10 changes: 10 additions & 0 deletions comscore/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Node artifact files
node_modules/
lib/
dist/

# Generated by MacOS
.DS_Store

# Generated by Windows
Thumbs.db
7 changes: 7 additions & 0 deletions comscore/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# @theoplayer/comscore-connector-web

## 1.0.21

### ✨ Features

- Initial release as a connector
106 changes: 106 additions & 0 deletions comscore/README.md
MattiasBuelens marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# comscore-connector-web

The Comscore connector provides a Comscore integration for THEOplayer.

## Installation

```sh
npm install @theoplayer/comscore-connector-web
```

This connector depends on the JavaScript ComScore SDK, which should be loaded and available in the global scope before the connector. Get it from your ComScore dashboard or talk to a ComScore representative. This connector was developed and tested with versions 7.2.0.200214 and 7.6.1.210506

```html
<script src="/path/to/comscore.js">
```

## Usage

### Configuring the connector

Create the connector by providing the `THEOplayer` instance, a ComscoreConfiguration (which contains your publisher id, also referred to as the c2 value) and the ComscoreMetadata of the first source being set to the player. You can change the metadata dynamically throughout the lifecycle of the connector.

```js
import { ComscoreConnector } from '../../dist/comscore-connector.esm.js';

const comscoreConfig = {
publisherId: '<your publisher id>',
applicationName: 'Test App',
userConsent: '1',
debug: true
};

const comscoreMetadata = {
mediaType: 'longFormOnDemand',
uniqueId: 'testuniqueId',
length: 634566, // in milliseconds
stationTitle: 'THEOTV',
programTitle: 'Big Buck Bunny',
episodeTitle: 'Intro',
genreName: 'Animation',
classifyAsAudioStream: false,
customLabels: {
testcustomlabel: 'testcustomvalue'
}
};

const comscoreConnector = new ComscoreConnector(player, comscoreConfig, comscoreMetadata);
```

### Passing metadata dynamically

The connector allows updating the current asset's metadata at any time. Do it when setting a new source to the player.

```js
comscoreConnector.updateMetadata(newMetadata);
```

### ComscoreMetadata fields

Based on the `ComscoreMetadata` type, you can tell which fields are mandatory and which aren't. Note that this is purely for the integration to work correctly. Depending on the Comscore solution you are using, different fields are required/optional. The mandatory fields in the `ComscoreMetadata` type are the ones that are mandatory for all three Comscore solutions:

- Video Metrix (V)
- Cross Platform Product Suite (X)
- Cross Media Audience Measurement (C)

| Property | Required | Optional |
| ---------------------------------- | :------: | :------: |
| `mediaType` | All | |
| `uniqueId` | All | |
| `length` | All | |
| `c3?` | V | |
| `c4?` | V | |
| `c6?` | V | |
| `stationTitle` | All | |
| `stationCode?` | | All |
| `networkAffiliate?` | | All |
| `publisherName?` | X C | V |
| `programTitle` | All | |
| `programId?` | | V C |
| `episodeTitle` | All | |
| `episodeId?` | | X C |
| `episodeSeasonNumber?` | X C | |
| `episodeNumber?` | X C | |
| `genreName` | All | |
| `genreId?` | | All |
| `carryTvAdvertisementLoad?` | X | |
| `classifyAsCompleteEpisode?` | X | |
| `dateOfProduction?` | | C |
| `timeOfProduction?` | | C |
| `dateOfTvAiring?` | X C | |
| `timeOfTvAiring?` | | X C |
| `dateOfDigitalAiring?` | X C | |
| `timeOfDigitalAiring?` | | X C |
| `feedType?` | X | |
| `classifyAsAudioStream` | Al | |
| `deliveryMode?` | | All |
| `deliverySubscriptionType?` | | All |
| `deliveryComposition?` | | All |
| `deliveryAdvertisementCapability?` | | All |
| `mediaFormat?` | | All |
| `distributionModel?` | | All |
| `playlistTitle?` | | C |
| `totalSegments?` | | V C |
| `clipUrl?` | | V C |
| `videoDimension?` | | C |
| `customLabels?` | | All |
39 changes: 39 additions & 0 deletions comscore/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "@theoplayer/comscore-connector-web",
"version": "1.0.20",
"description": "A connector implementing Comscore with THEOplayer",
"main": "dist/comscore-connector.umd.js",
"module": "dist/comscore-connector.esm.js",
"types": "dist/types/index.d.ts",
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/comscore-connector.esm.js",
"require": "./dist/comscore-connector.umd.js"
},
"./dist/*": "./dist/*",
"./package": "./package.json",
"./package.json": "./package.json"
},
"scripts": {
"clean": "rimraf lib dist",
"bundle": "rollup -c rollup.config.mjs",
"build": "npm run clean && npm run bundle",
"serve": "http-server ./.. -o /comscore/test/pages/main.html",
"test": "echo \"No tests yet\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/THEOplayer/web-connectors.git",
"directory": "comscore"
},
"author": "THEO Technologies NV",
"license": "MIT",
"bugs": {
"url": "https://github.com/THEOplayer/web-connectors/issues"
},
"homepage": "https://github.com/THEOplayer/web-connectors#readme",
"peerDependencies": {
"theoplayer": "^7.0.0"
}
}
15 changes: 15 additions & 0 deletions comscore/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import fs from "node:fs";
import {getSharedBuildConfiguration} from "../tools/build.mjs";


const {version} = JSON.parse(fs.readFileSync("./package.json", "utf8"));

const fileName = "comscore-connector";
const globalName = "THEOplayerComscoreConnector";

const banner = `
/**
* THEOplayer Comscore Web Connector v${version}
*/`.trim();

export default getSharedBuildConfiguration({fileName, globalName, banner});
31 changes: 31 additions & 0 deletions comscore/src/api/ComscoreConfiguration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Ad } from "theoplayer";

export enum ComscoreUserConsent {
denied = "0",
granted = "1",
unknown = ""
}

export enum ComscoreUsagePropertiesAutoUpdateMode {
foregroundOnly = "foregroundOnly",
foregroundAndBackground = "foregroundAndBackground",
disabled = "disabled"
}

export interface ComscoreConfiguration {
/**
* Also known as the c2 value
*/
publisherId: string;
applicationName: string;
userConsent: ComscoreUserConsent;
/**
* Defaults to foregroundOnly if none is specified. If your app has some background experience, use foregroundAndBackground.
*/
usagePropertiesAutoUpdateMode?: ComscoreUsagePropertiesAutoUpdateMode;
skeleton?: any;
adIdProcessor?: (ad: Ad) => string;
debug?: boolean;
}


99 changes: 99 additions & 0 deletions comscore/src/api/ComscoreConnector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { ChromelessPlayer } from 'theoplayer';
import type { ComscoreConfiguration, ComscoreUserConsent } from './ComscoreConfiguration';
import type { ComscoreMetadata } from './ComscoreMetadata';
import { ComscoreStreamingAnalyticsTHEOIntegration } from '../integration/ComscoreStreamingAnalyticsTHEOIntegration';

const USER_CONSENT_LABEL = "cs_ucfr"

export class ComscoreConnector {

private analytics = ns_.analytics
private configuration: ComscoreConfiguration
private streamingAnalyticsIntegration: ComscoreStreamingAnalyticsTHEOIntegration

/**
* Constructor for the THEOplayer Comscore connector
* @param player a THEOplayer instance reference
* @param comscoreConfig configuration object that should at least hold the publisher id, application name and an initial user consent value
* @param comscoreMetadata metadata associated with the SourceDescription that is or will be passed to the THEOplayer instance
* @returns
*/
constructor(player: ChromelessPlayer, comscoreConfig: ComscoreConfiguration, comscoreMetadata: ComscoreMetadata) {
if (typeof ns_ === 'undefined' || typeof this.analytics === 'undefined') {
throw new Error('[COMSCORE] ComScore script missing, cannot init ComScoreAnalytics');
}

this.configuration = comscoreConfig

// Set platform API
if (this.configuration.skeleton) {
this.analytics.PlatformApi.setPlatformAPI(this.analytics.PlatformAPIs.Skeleton, this.configuration.skeleton)
} else {
this.analytics.PlatformApi.setPlatformAPI(this.analytics.PlatformAPIs.html5)
}

// Configure publisher
const publisherConfiguration = new this.analytics.configuration.PublisherConfiguration({
publisherId: comscoreConfig.publisherId,
persistentLabels: {
[USER_CONSENT_LABEL]: comscoreConfig.userConsent || ""
}
})
this.analytics.configuration.addClient(publisherConfiguration)
this.analytics.configuration.setApplicationName(comscoreConfig.applicationName)


// Start application tracking
this.analytics.start()

// Set Streaming Analytics integration
this.streamingAnalyticsIntegration = new ComscoreStreamingAnalyticsTHEOIntegration(player, comscoreConfig, comscoreMetadata);
}

/**
* Sets/updates Comscore metadata on the Comscore video analytics.
* @param metadata object of key value pairs
*/
update(metadata: ComscoreMetadata): void {
this.streamingAnalyticsIntegration.update(metadata);
}

/**
* Update the user consent
* @param consentValue `"1"` indicates consent was granted, `"0"` not granted and `""` unknown.
*/
updateUserConsent(consentValue: ComscoreUserConsent): void {
this.analytics.configuration
.getPublisherConfiguration(this.configuration.publisherId)
.setPersistentLabel(USER_CONSENT_LABEL, consentValue);
this.analytics.notifyHiddenEvent()
}

/**
* Set persistent label on the ComScore PublisherConfiguration
* @param label
* @param value
*/
setPersistentLabel(label: string, value: string): void {
this.analytics.configuration
.getPublisherConfiguration(this.configuration.publisherId)
.setPersistentLabel(label,value);
}

/**
* Set persistent labels on the ComScore PublisherConfiguration
* @param labels object of key value pairs
*/
setPersistentLabels(labels: { [key: string]: string }): void {
this.analytics.configuration
.getPublisherConfiguration(this.configuration.publisherId)
.setPersistentLabels(labels);
}

/**
* Destroy ComScoreStreamingAnalytics and unregister it from player
*/
destroy(): void {
this.streamingAnalyticsIntegration.destroy();
}
}
Loading