diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d9e47b..8889c97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added + +- `AdImmunityConfig.disablePassedAdBreaks` option to only temporarily disable ad breaks during the ad immunity instead of disabling them for the whole session + ## [2.6.0] - 2024-09-25 ### Changed diff --git a/src/ts/BitmovinYospacePlayerAPI.ts b/src/ts/BitmovinYospacePlayerAPI.ts index a852872..1400f7f 100644 --- a/src/ts/BitmovinYospacePlayerAPI.ts +++ b/src/ts/BitmovinYospacePlayerAPI.ts @@ -71,17 +71,15 @@ export interface BitmovinYospacePlayerAPI extends PlayerAPI { forceSeek(time: number, issuer?: string): boolean; /** - * Provide a duration in seconds greater than 0 to enable the ad immunity feature. - * The user will become immune to ad breaks for the duration upon - * fully watching an ad break. + * Provide a duration in seconds greater than 0 to enable the ad immunity feature. The user will become immune to ad + * breaks for the duration upon fully watching an ad break. * - * Ad breaks played over or seeked past during immunity will be marked - * as deactivated, making the user permanently immune to those breaks. + * Ad breaks played over or seeked past during immunity will be marked as deactivated, making the user permanently + * immune to those breaks (unless `AdImmunityConfig.disablePassedAdBreaks` is set to `false`). * - * Post-rolls are excluded from ad immunity + * Post-rolls are excluded from ad immunity. * - * Pre-roll ads are excluded from ad immunity as at least one ad break needs to be - * watched completely + * Pre-roll ads are excluded from ad immunity as at least one ad break needs to be watched completely. */ setAdImmunityConfig(options: AdImmunityConfig): void; @@ -153,7 +151,6 @@ export interface YospaceConfiguration { debug?: boolean; debugYospaceSdk?: boolean; disableServiceWorker?: boolean; - disableStrictBreaks?: boolean; useTizen?: boolean; useWebos?: boolean; } @@ -267,13 +264,22 @@ export interface AdImmunityEndedEvent extends YospaceEventBase { type: YospacePlayerEvent.AdImmunityEnded; } -/** - * @description Ad Immunity Configuration Object - * @property duration - a number indicating the duration of the ad immunity period. 0 disables the feature. - * @property adBreakCheckOffset - a number indicating how far ahead ad immunity should look for ad breaks - * to skip past, in order to mitigate ad frames being displayed before they have time to be seeked past. - */ export interface AdImmunityConfig { + /** + * A number indicating the duration in seconds of the ad immunity period. 0 disables the feature. + */ duration: number; + + /** + * A number indicating how far ahead ad immunity should look for ad breaks to skip past, in order to mitigate ad + * frames being displayed before they have time to be seeked past. + */ adBreakCheckOffset?: number; + + /** + * Flag to set if ad breaks the user passes during active ad immunity, by playing or seeking, should be disabled + * or not. Disabled ad breaks won't be shown to the user again in this session. + * Default is true (ad breaks will be disabled). + */ + disablePassedAdBreaks?: boolean; } diff --git a/src/ts/InternalBitmovinYospacePlayer.ts b/src/ts/InternalBitmovinYospacePlayer.ts index 2905a18..589d6fd 100644 --- a/src/ts/InternalBitmovinYospacePlayer.ts +++ b/src/ts/InternalBitmovinYospacePlayer.ts @@ -156,6 +156,7 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { }; // Ad holiday offset for discovering upcoming ad breaks before an ad frame is shown to the user private defaultAdBreakCheckOffset = 0.3; + private defaultDisablePassedAdBreaks = true; private adImmune = false; private adImmunityCountDown: number | null = null; @@ -412,7 +413,7 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { const breakStart = this.toMagicTime(toSeconds(adBreak.getStart())); // Check if break is being seeked past and deactivate it - if (breakStart > currentTime && breakStart <= time) { + if (breakStart > currentTime && breakStart <= time && this.adImmunityConfig.disablePassedAdBreaks) { Logger.log('[BitmovinYospacePlayer] Ad Immunity deactivated ad break during seek', adBreak); adBreak.setInactive(); } @@ -573,6 +574,7 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { setAdImmunityConfig(config: AdImmunityConfig) { this.adImmunityConfig = { + disablePassedAdBreaks: this.defaultDisablePassedAdBreaks, ...this.adImmunityConfig, ...config, }; @@ -1246,9 +1248,12 @@ export class InternalBitmovinYospacePlayer implements BitmovinYospacePlayerAPI { // seek past and deactivate ad breaks entered during ad immunity if (upcomingAdBreak && this.adImmune) { - upcomingAdBreak.setInactive(); - - Logger.log('[BitmovinYospacePlayer] - Ad Immunity pausing, seeking past and deactivating ad break'); + if (this.adImmunityConfig.disablePassedAdBreaks) { + upcomingAdBreak.setInactive(); + Logger.log('[BitmovinYospacePlayer] - Ad Immunity pausing, seeking past and deactivating ad break'); + } else { + Logger.log('[BitmovinYospacePlayer] - Ad Immunity pausing, seeking past but not deactivating ad break'); + } this.performBreakSkip(toSeconds(upcomingAdBreak.getStart() + upcomingAdBreak.getDuration())); diff --git a/web/index.html b/web/index.html index c96ceba..70faa44 100644 --- a/web/index.html +++ b/web/index.html @@ -216,7 +216,6 @@ var yospaceConfig = { debug: debugOverride && !isValidationMode, debugYospaceSdk: isValidationMode, - disableStrictBreaks: false, disableServiceWorker: false, useTizen: platformType === 'tizen', useWebos: platformType === 'webos',