Skip to content

Commit

Permalink
fix(FEC-11047): IMA DAI display container on preload and handling fla…
Browse files Browse the repository at this point in the history
…gs too soon (#60)

Issue: IMA DAI firing the adbreakstart when the media is loaded so the IMA DAI container is showing when it's not started yet.
Solution: we already delayed the event until the playback is actually started, added handling for flags, and internal implementation changes on delay as well.
  • Loading branch information
Yuvalke authored Mar 10, 2021
1 parent 606020b commit f635da8
Showing 1 changed file with 39 additions and 12 deletions.
51 changes: 39 additions & 12 deletions src/ima-dai.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ class ImaDAI extends BasePlugin implements IAdsControllerProvider, IEngineDecora
_queue: ImaDAIEventQueue;
_firstPlay: boolean;

/**
* an object containing all delayed events from our SDK for IMA DAI events.
* @member {Map} - _delayedEventBindings
* @type {Map}
* @private
*/
_delayedEventBindings: Map<string, Function>;

static IMA_DAI_SDK_LIB_URL: string = '//imasdk.googleapis.com/js/sdkloader/ima3_dai.js';

static IMA_DAI_SDK_DEBUG_LIB_URL: string = '//imasdk.googleapis.com/js/sdkloader/ima3_dai_debug.js';
Expand Down Expand Up @@ -416,18 +424,23 @@ class ImaDAI extends BasePlugin implements IAdsControllerProvider, IEngineDecora

_attachStreamManagerListeners(): void {
this.logger.debug('Attach stream manager listeners');
this._delayedEventBindings = new Map();
this._delayedEventBindings.set(EventType.AD_BREAK_START, e => this._onAdBreakStarted(e));
this._delayedEventBindings.set(EventType.AD_COMPLETED, () => this._onAdComplete());
this._delayedEventBindings.set(EventType.AD_CLICKED, () => this._onAdClick());

this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.LOADED, e => this._onLoaded(e));
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.ERROR, e => this._onError(e));
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.CUEPOINTS_CHANGED, e => this._onCuePointsChanged(e));
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.AD_BREAK_STARTED, () => this._onAdBreakStarted());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.AD_BREAK_STARTED, () => this._onAdBreakStartedFromSDK());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.AD_BREAK_ENDED, () => this._onAdBreakEnded());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.AD_PROGRESS, e => this._onAdProgress(e));
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.STARTED, e => this._onAdStarted(e));
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.FIRST_QUARTILE, () => this._onAdFirstQuartile());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.MIDPOINT, () => this._onAdMidpoint());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.THIRD_QUARTILE, () => this._onAdThirdQuartile());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.COMPLETE, () => this._onAdComplete());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.CLICK, () => this._onAdClick());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.COMPLETE, () => this._onAdCompleteFromSDK());
this._streamManager.addEventListener(this._sdk.api.StreamEvent.Type.CLICK, () => this._onAdClickFromSDK());
}

_requestVODStream(): void {
Expand Down Expand Up @@ -465,14 +478,18 @@ class ImaDAI extends BasePlugin implements IAdsControllerProvider, IEngineDecora
this.logger.debug('Cue points changed', this._cuePoints);
}

_onAdBreakStarted(): void {
_onAdBreakStartedFromSDK(): void {
const adBreakOptions = this._getAdBreakOptions();
if (this._shouldIgnorePreroll(adBreakOptions)) {
return;
}
this._adBreak = true;
Utils.Dom.setAttribute(this._adsContainerDiv, 'data-adtype', adBreakOptions.type);
this._dispatchAdEvent(EventType.AD_BREAK_START, {adBreak: new AdBreak(adBreakOptions)});
}

_onAdBreakStarted(event: Object): void {
const {payload} = event;
this._adBreak = true;
Utils.Dom.setAttribute(this._adsContainerDiv, 'data-adtype', payload.adBreak.type);
this._showAdsContainer();
this._playbackRate = this.player.playbackRate;
this.player.playbackRate !== 1 && (this.player.playbackRate = 1);
Expand All @@ -482,16 +499,16 @@ class ImaDAI extends BasePlugin implements IAdsControllerProvider, IEngineDecora
if (this._ignorePreroll) {
return;
}
if (!this._adStartedDispatched) {
this._onAdStarted(event);
}
const adProgressData = event.getStreamData().adProgressData;
this._dispatchAdEvent(EventType.AD_PROGRESS, {
adProgress: {
currentTime: adProgressData.currentTime,
duration: adProgressData.duration
}
});
if (!this._adStartedDispatched) {
this._onAdStarted(event);
}
}

_onAdStarted(event: Object): void {
Expand Down Expand Up @@ -521,22 +538,28 @@ class ImaDAI extends BasePlugin implements IAdsControllerProvider, IEngineDecora
this._dispatchAdEvent(EventType.AD_THIRD_QUARTILE);
}

_onAdCompleteFromSDK(): void {
this._dispatchAdEvent(EventType.AD_COMPLETED);
}

_onAdComplete(): void {
this._state = ImaDAIState.IDLE;
this._dispatchAdEvent(EventType.AD_COMPLETED);
this._adStartedDispatched = false;
}

_onAdClick(): void {
_onAdClickFromSDK(): void {
this.logger.debug('On ad clicked');
this._dispatchAdEvent(EventType.AD_CLICKED);
}

_onAdClick(): void {
if (this._shouldPauseOnAdClick()) {
this._setToggleAdsCover(true);
if (this._state === ImaDAIState.PLAYING) {
this.player.pause();
this.pauseAd();
}
}
this._dispatchAdEvent(EventType.AD_CLICKED);
}

_onAdBreakEnded(): void {
Expand Down Expand Up @@ -652,6 +675,10 @@ class ImaDAI extends BasePlugin implements IAdsControllerProvider, IEngineDecora
this._queue.push({type, payload});
} else {
this.logger.debug(type.toUpperCase(), payload);
const callback = this._delayedEventBindings.get(type);
if (callback && typeof callback === 'function') {
callback({type, payload});
}
this.dispatchEvent(type, payload);
}
}
Expand Down

0 comments on commit f635da8

Please sign in to comment.