From c1e1a72b4184e7231d0377e0e0d6d91b59ff1d98 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Thu, 28 Mar 2024 10:24:47 +0100 Subject: [PATCH 1/8] Upgrade conviva dependency --- conviva/package.json | 6 +++--- package-lock.json | 8 +------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/conviva/package.json b/conviva/package.json index c257b7de..84a219ec 100644 --- a/conviva/package.json +++ b/conviva/package.json @@ -34,11 +34,11 @@ "package.json" ], "dependencies": { - "@convivainc/conviva-js-coresdk": "^4.6.1" + "@convivainc/conviva-js-coresdk": "^4.7.4" }, "peerDependencies": { - "theoplayer": "^5.0.0 || ^6.0.0", - "@theoplayer/yospace-connector-web": "^2.1.0" + "@theoplayer/yospace-connector-web": "^2.1.0", + "theoplayer": "^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { "@theoplayer/yospace-connector-web": { diff --git a/package-lock.json b/package-lock.json index 8e26ad78..e56e9466 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "version": "2.0.0", "license": "MIT", "dependencies": { - "@convivainc/conviva-js-coresdk": "^4.6.1" + "@convivainc/conviva-js-coresdk": "^4.7.4" }, "peerDependencies": { "@theoplayer/yospace-connector-web": "^2.1.0", @@ -75,12 +75,6 @@ "theoplayer": "^5.0.0 || ^6.0.0" } }, - "nielsen/node_modules/theoplayer": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/theoplayer/-/theoplayer-5.11.0.tgz", - "integrity": "sha512-Ywn3nnTPiyh0cckO3FGIvXfhr3BR16D967voMthnQlwY5jITEJq6pKYAt9qHEXyWNafULKVhY0X///61Wxm7lw==", - "peer": true - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", From ae0021986fe56015229ab7bbe67a00ae696e2278 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Fri, 1 Dec 2023 18:35:47 +0100 Subject: [PATCH 2/8] Add ad extension --- conviva/src/integration/ads/CsaiAdReporter.ts | 40 +++++++++---------- .../extension/ConvivaAdEventsExtension.d.ts | 10 +++++ 2 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts diff --git a/conviva/src/integration/ads/CsaiAdReporter.ts b/conviva/src/integration/ads/CsaiAdReporter.ts index 76b0da9a..ccec4986 100644 --- a/conviva/src/integration/ads/CsaiAdReporter.ts +++ b/conviva/src/integration/ads/CsaiAdReporter.ts @@ -116,33 +116,29 @@ export class CsaiAdReporter { private addEventListeners(): void { this.player.addEventListener('playing', this.onPlaying); this.player.addEventListener('pause', this.onPause); - if (this.player.ads === undefined) { - // should not happen - return; - } - this.player.ads.addEventListener('adbreakbegin', this.onAdBreakBegin); - this.player.ads.addEventListener('adbreakend', this.onAdBreakEnd); - this.player.ads.addEventListener('adbegin', this.onAdBegin); - this.player.ads.addEventListener('adend', this.onAdEnd); - this.player.ads.addEventListener('adskip', this.onAdSkip); - this.player.ads.addEventListener('adbuffering', this.onAdBuffering); - this.player.ads.addEventListener('aderror', this.onAdError); + [this.player.ads, this.player.ads?.convivaAdEventsExtension].forEach((dispatcher)=> { + dispatcher?.addEventListener('adbreakbegin', this.onAdBreakBegin); + dispatcher?.addEventListener('adbreakend', this.onAdBreakEnd); + dispatcher?.addEventListener('adbegin', this.onAdBegin); + dispatcher?.addEventListener('adend', this.onAdEnd); + dispatcher?.addEventListener('adskip', this.onAdSkip); + dispatcher?.addEventListener('adbuffering', this.onAdBuffering); + dispatcher?.addEventListener('aderror', this.onAdError); + }); } private removeEventListeners(): void { this.player.removeEventListener('playing', this.onPlaying); this.player.removeEventListener('pause', this.onPause); - if (this.player.ads === undefined) { - // should not happen - return; - } - this.player.ads.removeEventListener('adbreakbegin', this.onAdBreakBegin); - this.player.ads.removeEventListener('adbreakend', this.onAdBreakEnd); - this.player.ads.removeEventListener('adbegin', this.onAdBegin); - this.player.ads.removeEventListener('adend', this.onAdEnd); - this.player.ads.removeEventListener('adskip', this.onAdSkip); - this.player.ads.removeEventListener('adbuffering', this.onAdBuffering); - this.player.ads.removeEventListener('aderror', this.onAdError); + [this.player.ads, this.player.ads?.convivaAdEventsExtension].forEach((dispatcher)=> { + dispatcher?.removeEventListener('adbreakbegin', this.onAdBreakBegin); + dispatcher?.removeEventListener('adbreakend', this.onAdBreakEnd); + dispatcher?.removeEventListener('adbegin', this.onAdBegin); + dispatcher?.removeEventListener('adend', this.onAdEnd); + dispatcher?.removeEventListener('adskip', this.onAdSkip); + dispatcher?.removeEventListener('adbuffering', this.onAdBuffering); + dispatcher?.removeEventListener('aderror', this.onAdError); + }); } reset(): void { diff --git a/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts b/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts new file mode 100644 index 00000000..cd637d6a --- /dev/null +++ b/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts @@ -0,0 +1,10 @@ +import { AdsEventMap, EventDispatcher } from "theoplayer"; + +declare module "theoplayer" { + interface Ads extends EventDispatcher { + convivaAdEventsExtension?: EventDispatcher; + } + class ChromelessPlayer { + ads?: Ads; + } +} From e6c9869c5e05eb45e4bf411b607be3cbb96a75ed Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Fri, 8 Dec 2023 15:38:15 -0800 Subject: [PATCH 3/8] Report ssai ads # Conflicts: # conviva/src/utils/Utils.ts --- conviva/src/integration/ConvivaHandler.ts | 14 ++++++-------- conviva/src/integration/ads/CsaiAdReporter.ts | 12 ++++++++++-- conviva/src/utils/Utils.ts | 9 ++++++--- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/conviva/src/integration/ConvivaHandler.ts b/conviva/src/integration/ConvivaHandler.ts index 86c2a8dc..6a7a5679 100644 --- a/conviva/src/integration/ConvivaHandler.ts +++ b/conviva/src/integration/ConvivaHandler.ts @@ -62,14 +62,12 @@ export class ConvivaHandler { this.convivaAdAnalytics = Analytics.buildAdAnalytics(this.convivaVideoAnalytics); - if (this.player.ads !== undefined) { - this.adReporter = new CsaiAdReporter( - this.player, - this.convivaVideoAnalytics, - this.convivaAdAnalytics, - () => this.customMetadata - ); - } + this.adReporter = new CsaiAdReporter( + this.player, + this.convivaVideoAnalytics, + this.convivaAdAnalytics, + () => this.customMetadata + ); if (this.player.verizonMedia !== undefined) { this.verizonAdReporter = new VerizonAdReporter( diff --git a/conviva/src/integration/ads/CsaiAdReporter.ts b/conviva/src/integration/ads/CsaiAdReporter.ts index ccec4986..d4dff04b 100644 --- a/conviva/src/integration/ads/CsaiAdReporter.ts +++ b/conviva/src/integration/ads/CsaiAdReporter.ts @@ -1,6 +1,6 @@ import { Ad, AdBreak, ChromelessPlayer, GoogleImaAd } from 'theoplayer'; import { AdAnalytics, Constants, ConvivaMetadata, VideoAnalytics } from '@convivainc/conviva-js-coresdk'; -import { calculateCurrentAdBreakInfo, collectAdMetadata, collectPlayerInfo } from '../../utils/Utils'; +import { calculateAdType, calculateCurrentAdBreakInfo, collectAdMetadata, collectPlayerInfo } from '../../utils/Utils'; export class CsaiAdReporter { private readonly player: ChromelessPlayer; @@ -29,7 +29,7 @@ export class CsaiAdReporter { private readonly onAdBreakBegin = (event: any) => { this.currentAdBreak = event.ad as AdBreak; this.convivaVideoAnalytics.reportAdBreakStarted( - Constants.AdType.CLIENT_SIDE, + calculateAdType(this.player), Constants.AdPlayer.CONTENT, calculateCurrentAdBreakInfo(this.currentAdBreak, this.adBreakCounter) ); @@ -57,6 +57,9 @@ export class CsaiAdReporter { adMetadata.contentAssetName = this.contentInfo()[Constants.ASSET_NAME] ?? this.player.source?.metadata?.title ?? 'NA'; + // [Required] The ad technology as CLIENT_SIDE/SERVER_SIDE + adMetadata['c3.ad.technology'] = calculateAdType(this.player); + this.convivaAdAnalytics.setAdInfo(adMetadata); this.convivaAdAnalytics.reportAdLoaded(adMetadata); this.convivaAdAnalytics.reportAdStarted(adMetadata); @@ -66,6 +69,11 @@ export class CsaiAdReporter { this.player.videoHeight ); this.convivaAdAnalytics.reportAdMetric(Constants.Playback.BITRATE, (currentAd as GoogleImaAd).bitrate || 0); + + // Report playing state in case of SSAI. + if (calculateAdType(this.player) === Constants.AdType.SERVER_SIDE) { + this.convivaAdAnalytics.reportAdMetric(Constants.Playback.PLAYER_STATE, Constants.PlayerState.PLAYING); + } }; private readonly onAdEnd = (event: any) => { diff --git a/conviva/src/utils/Utils.ts b/conviva/src/utils/Utils.ts index 15b8e0fe..c57654f9 100644 --- a/conviva/src/utils/Utils.ts +++ b/conviva/src/utils/Utils.ts @@ -17,6 +17,12 @@ export function collectDeviceMetadata(): ConvivaDeviceMetadata { }; } +type AdBreakPosition = 'preroll' | 'midroll' | 'postroll'; + +export function calculateAdType(player: ChromelessPlayer) { + return player.source?.ads?.length ? Constants.AdType.CLIENT_SIDE : Constants.AdType.SERVER_SIDE; +} + export function calculateVerizonAdBreakInfo(adBreak: VerizonMediaAdBreak, adBreakIndex: number): ConvivaAdBreakInfo { return { [Constants.POD_DURATION]: adBreak.duration!, @@ -132,9 +138,6 @@ export function collectAdMetadata(ad: Ad): ConvivaMetadata { // For wrapper ads, this is the last creative id at the end of the wrapper chain. Set to "NA" if not available. adMetadata['c3.ad.creativeId'] = ad.creativeId || 'NA'; - // [Required] The ad technology as CLIENT_SIDE/SERVER_SIDE - adMetadata['c3.ad.technology'] = Constants.AdType.CLIENT_SIDE; - // [Required] The ad position as a string "Pre-roll", "Mid-roll" or "Post-roll" adMetadata['c3.ad.position'] = calculateCurrentAdBreakPosition(ad.adBreak); From cea3a7252d4e488cdb86f37d77454f7fa1ed1746 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Fri, 29 Mar 2024 09:32:18 +0100 Subject: [PATCH 4/8] Rename ad reporter --- conviva/src/integration/ConvivaHandler.ts | 6 +++--- .../integration/ads/{CsaiAdReporter.ts => AdReporter.ts} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename conviva/src/integration/ads/{CsaiAdReporter.ts => AdReporter.ts} (99%) diff --git a/conviva/src/integration/ConvivaHandler.ts b/conviva/src/integration/ConvivaHandler.ts index 6a7a5679..fff97967 100644 --- a/conviva/src/integration/ConvivaHandler.ts +++ b/conviva/src/integration/ConvivaHandler.ts @@ -10,7 +10,7 @@ import { collectPlayerInfo, flattenAndStringifyObject } from '../utils/Utils'; -import { CsaiAdReporter } from './ads/CsaiAdReporter'; +import { AdReporter } from './ads/AdReporter'; import { YospaceAdReporter } from './ads/YospaceAdReporter'; import { VerizonAdReporter } from './ads/VerizonAdReporter'; @@ -29,7 +29,7 @@ export class ConvivaHandler { private convivaVideoAnalytics: VideoAnalytics | undefined; private convivaAdAnalytics: AdAnalytics | undefined; - private adReporter: CsaiAdReporter | undefined; + private adReporter: AdReporter | undefined; private yospaceAdReporter: YospaceAdReporter | undefined; private verizonAdReporter: VerizonAdReporter | undefined; @@ -62,7 +62,7 @@ export class ConvivaHandler { this.convivaAdAnalytics = Analytics.buildAdAnalytics(this.convivaVideoAnalytics); - this.adReporter = new CsaiAdReporter( + this.adReporter = new AdReporter( this.player, this.convivaVideoAnalytics, this.convivaAdAnalytics, diff --git a/conviva/src/integration/ads/CsaiAdReporter.ts b/conviva/src/integration/ads/AdReporter.ts similarity index 99% rename from conviva/src/integration/ads/CsaiAdReporter.ts rename to conviva/src/integration/ads/AdReporter.ts index d4dff04b..adf367e4 100644 --- a/conviva/src/integration/ads/CsaiAdReporter.ts +++ b/conviva/src/integration/ads/AdReporter.ts @@ -2,7 +2,7 @@ import { Ad, AdBreak, ChromelessPlayer, GoogleImaAd } from 'theoplayer'; import { AdAnalytics, Constants, ConvivaMetadata, VideoAnalytics } from '@convivainc/conviva-js-coresdk'; import { calculateAdType, calculateCurrentAdBreakInfo, collectAdMetadata, collectPlayerInfo } from '../../utils/Utils'; -export class CsaiAdReporter { +export class AdReporter { private readonly player: ChromelessPlayer; private readonly convivaVideoAnalytics: VideoAnalytics; private readonly convivaAdAnalytics: AdAnalytics; From 1573e219736b92a9badf9e8e8ddcbf469ad7e027 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Wed, 13 Dec 2023 12:04:06 -0800 Subject: [PATCH 5/8] Add custom event reporting API --- conviva/src/integration/ConvivaConnector.ts | 9 +++++++++ conviva/src/integration/ConvivaHandler.ts | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/conviva/src/integration/ConvivaConnector.ts b/conviva/src/integration/ConvivaConnector.ts index 72ccbbc3..da910947 100644 --- a/conviva/src/integration/ConvivaConnector.ts +++ b/conviva/src/integration/ConvivaConnector.ts @@ -42,6 +42,15 @@ export class ConvivaConnector { this.convivaHandler.reportPlaybackFailed(errorMessage); } + /** + * Reports a custom event to the current Conviva session. + * @param eventType the type of the custom event. + * @param eventDetail an optional object containing event details. + */ + reportPlaybackEvent(eventType: string, eventDetail?: object): void { + this.convivaHandler.reportPlaybackEvent(eventType, eventDetail); + } + /** * Explicitly stop the current session and start a new one. * diff --git a/conviva/src/integration/ConvivaHandler.ts b/conviva/src/integration/ConvivaHandler.ts index fff97967..fd4ce07a 100644 --- a/conviva/src/integration/ConvivaHandler.ts +++ b/conviva/src/integration/ConvivaHandler.ts @@ -121,6 +121,10 @@ export class ConvivaHandler { this.releaseSession(); } + reportPlaybackEvent(eventType: string, eventDetail?: object): void { + this.convivaVideoAnalytics?.reportPlaybackEvent(eventType, eventDetail); + } + stopAndStartNewSession(metadata: ConvivaMetadata): void { this.maybeReportPlaybackEnded(); this.maybeReportPlaybackRequested(); From 1482d460aecaf3ebeba70d56112ab56ad754ab10 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Fri, 29 Mar 2024 09:37:46 +0100 Subject: [PATCH 6/8] Run prettier --- conviva/src/integration/ads/AdReporter.ts | 4 ++-- .../src/integration/extension/ConvivaAdEventsExtension.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/conviva/src/integration/ads/AdReporter.ts b/conviva/src/integration/ads/AdReporter.ts index adf367e4..586e5386 100644 --- a/conviva/src/integration/ads/AdReporter.ts +++ b/conviva/src/integration/ads/AdReporter.ts @@ -124,7 +124,7 @@ export class AdReporter { private addEventListeners(): void { this.player.addEventListener('playing', this.onPlaying); this.player.addEventListener('pause', this.onPause); - [this.player.ads, this.player.ads?.convivaAdEventsExtension].forEach((dispatcher)=> { + [this.player.ads, this.player.ads?.convivaAdEventsExtension].forEach((dispatcher) => { dispatcher?.addEventListener('adbreakbegin', this.onAdBreakBegin); dispatcher?.addEventListener('adbreakend', this.onAdBreakEnd); dispatcher?.addEventListener('adbegin', this.onAdBegin); @@ -138,7 +138,7 @@ export class AdReporter { private removeEventListeners(): void { this.player.removeEventListener('playing', this.onPlaying); this.player.removeEventListener('pause', this.onPause); - [this.player.ads, this.player.ads?.convivaAdEventsExtension].forEach((dispatcher)=> { + [this.player.ads, this.player.ads?.convivaAdEventsExtension].forEach((dispatcher) => { dispatcher?.removeEventListener('adbreakbegin', this.onAdBreakBegin); dispatcher?.removeEventListener('adbreakend', this.onAdBreakEnd); dispatcher?.removeEventListener('adbegin', this.onAdBegin); diff --git a/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts b/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts index cd637d6a..d6c4490a 100644 --- a/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts +++ b/conviva/src/integration/extension/ConvivaAdEventsExtension.d.ts @@ -1,6 +1,6 @@ -import { AdsEventMap, EventDispatcher } from "theoplayer"; +import { AdsEventMap, EventDispatcher } from 'theoplayer'; -declare module "theoplayer" { +declare module 'theoplayer' { interface Ads extends EventDispatcher { convivaAdEventsExtension?: EventDispatcher; } From a60317c3ae4499d9565136158d00b1883eacdf92 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Fri, 29 Mar 2024 09:44:41 +0100 Subject: [PATCH 7/8] Add changeset --- .changeset/tough-hornets-sneeze.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tough-hornets-sneeze.md diff --git a/.changeset/tough-hornets-sneeze.md b/.changeset/tough-hornets-sneeze.md new file mode 100644 index 00000000..8a1e2f24 --- /dev/null +++ b/.changeset/tough-hornets-sneeze.md @@ -0,0 +1,5 @@ +--- +"@theoplayer/conviva-connector-web": patch +--- + +Added functionality to listen for external ad events using the `convivaAdEventsExtension` property. From b1f71c02561d9855e36d046de09cb696638c7f32 Mon Sep 17 00:00:00 2001 From: Tom Van Laerhoven Date: Wed, 3 Apr 2024 14:33:57 +0200 Subject: [PATCH 8/8] Add support for sdk version 7.0 --- conviva/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conviva/package.json b/conviva/package.json index 84a219ec..5b298859 100644 --- a/conviva/package.json +++ b/conviva/package.json @@ -38,7 +38,7 @@ }, "peerDependencies": { "@theoplayer/yospace-connector-web": "^2.1.0", - "theoplayer": "^5.0.0 || ^6.0.0" + "theoplayer": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "peerDependenciesMeta": { "@theoplayer/yospace-connector-web": {