Merge pull request #761 from gehaktmolen/beta-with-ads-promises
Beta with ads - Added promises, missing events, new ad tag and additional logging.
This commit is contained in:
commit
c24c05226d
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ index-*.html
|
|||||||
npm-debug.log
|
npm-debug.log
|
||||||
*.webm
|
*.webm
|
||||||
/package-lock.json
|
/package-lock.json
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
@ -52,8 +52,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
|
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
|
||||||
},
|
},
|
||||||
ads: {
|
ads: {
|
||||||
tagUrl:
|
tagUrl: 'https://pubads.g.doubleclick.net/gampad/ads' +
|
||||||
'http://go.aniview.com/api/adserver6/vast/?AV_PUBLISHERID=58c25bb0073ef448b1087ad6&AV_CHANNELID=5a0458dc28a06145e4519d21&AV_URL=127.0.0.1:3000&cb=1&AV_WIDTH=640&AV_HEIGHT=480',
|
'?sz=640x480&iu=/124319096/external/ad_rule_samples&' +
|
||||||
|
'ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&' +
|
||||||
|
'output=vmap&unviewed_position_start=1&cust_params=d' +
|
||||||
|
'eployment%3Ddevsite%26sample_ar%3Dpremidpostoptimiz' +
|
||||||
|
'edpod&cmsid=496&vid=short_onecue&correlator=',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import utils from '../utils';
|
import utils from '../utils';
|
||||||
|
|
||||||
// Events are different on various devices. We det the correct events, based on userAgent.
|
// Events are different on various devices. We set the correct events, based on userAgent.
|
||||||
const getStartEvents = () => {
|
const getStartEvents = () => {
|
||||||
let events = ['click'];
|
let events = ['click'];
|
||||||
|
|
||||||
@ -38,16 +38,43 @@ export default class Ads {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
|
this.time = Date.now();
|
||||||
this.startEvents = getStartEvents();
|
this.startEvents = getStartEvents();
|
||||||
this.adDisplayContainer = null;
|
this.adDisplayContainer = null;
|
||||||
this.adDisplayElement = null;
|
this.adDisplayElement = null;
|
||||||
this.adsManager = null;
|
this.adsManager = null;
|
||||||
this.adsLoader = null;
|
this.adsLoader = null;
|
||||||
this.adCuePoints = null;
|
this.adsCuePoints = null;
|
||||||
this.currentAd = null;
|
this.currentAd = null;
|
||||||
this.events = {};
|
this.events = {};
|
||||||
|
this.safetyTimer = null;
|
||||||
this.videoElement = document.createElement('video');
|
this.videoElement = document.createElement('video');
|
||||||
|
|
||||||
|
// Setup a simple promise to resolve if the IMA loader is ready.
|
||||||
|
this.adsLoaderResolve = () => {};
|
||||||
|
this.adsLoaderPromise = new Promise((resolve) => {
|
||||||
|
this.adsLoaderResolve = resolve;
|
||||||
|
});
|
||||||
|
this.adsLoaderPromise.then(() => {
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] adsLoader resolved!`, this.adsLoader);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Setup a promise to resolve if the IMA manager is ready.
|
||||||
|
this.adsManagerResolve = () => {};
|
||||||
|
this.adsManagerPromise = new Promise((resolve) => {
|
||||||
|
// Resolve our promise.
|
||||||
|
this.adsManagerResolve = resolve;
|
||||||
|
});
|
||||||
|
this.adsManagerPromise.then(() => {
|
||||||
|
// Clear the safety timer.
|
||||||
|
this.clearSafetyTimer('onAdsManagerLoaded()');
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] adsManager resolved!`, this.adsManager);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start ticking our safety timer. If the whole advertisement
|
||||||
|
// thing doesn't resolve within our set time; we bail.
|
||||||
|
this.startSafetyTimer(12000, 'ready()');
|
||||||
|
|
||||||
// Setup the ad display container.
|
// Setup the ad display container.
|
||||||
this.setupAdDisplayContainer();
|
this.setupAdDisplayContainer();
|
||||||
|
|
||||||
@ -83,6 +110,8 @@ export default class Ads {
|
|||||||
adsRequest.nonLinearAdSlotHeight = container.offsetHeight;
|
adsRequest.nonLinearAdSlotHeight = container.offsetHeight;
|
||||||
|
|
||||||
this.adsLoader.requestAds(adsRequest);
|
this.adsLoader.requestAds(adsRequest);
|
||||||
|
|
||||||
|
this.adsLoaderResolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdsManagerLoaded(adsManagerLoadedEvent) {
|
onAdsManagerLoaded(adsManagerLoadedEvent) {
|
||||||
@ -111,6 +140,9 @@ export default class Ads {
|
|||||||
this.adsManager.addEventListener(window.google.ima.AdEvent.Type.LOADED, event => this.onAdEvent(event));
|
this.adsManager.addEventListener(window.google.ima.AdEvent.Type.LOADED, event => this.onAdEvent(event));
|
||||||
this.adsManager.addEventListener(window.google.ima.AdEvent.Type.STARTED, event => this.onAdEvent(event));
|
this.adsManager.addEventListener(window.google.ima.AdEvent.Type.STARTED, event => this.onAdEvent(event));
|
||||||
this.adsManager.addEventListener(window.google.ima.AdEvent.Type.COMPLETE, event => this.onAdEvent(event));
|
this.adsManager.addEventListener(window.google.ima.AdEvent.Type.COMPLETE, event => this.onAdEvent(event));
|
||||||
|
|
||||||
|
// Resolve our adsManager.
|
||||||
|
this.adsManagerResolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdEvent(event) {
|
onAdEvent(event) {
|
||||||
@ -127,9 +159,58 @@ export default class Ads {
|
|||||||
// let intervalTimer;
|
// let intervalTimer;
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case window.google.ima.AdEvent.Type.LOADED:
|
|
||||||
|
case google.ima.AdEvent.Type.AD_BREAK_READY:
|
||||||
|
// This event indicates that a mid-roll ad is ready to start.
|
||||||
|
// We pause the player and tell the adsManager to start playing the ad.
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] AD_BREAK_READY |`, 'Fired when an ad rule or a VMAP ad break would have played if autoPlayAdBreaks is false.');
|
||||||
|
|
||||||
|
this.player.pause();
|
||||||
|
|
||||||
|
this.adsManager.start();
|
||||||
|
|
||||||
|
this.handleEventListeners('AD_BREAK_READY');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.AD_METADATA:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] AD_METADATA |`, 'Fired when an ads list is loaded.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] ALL_ADS_COMPLETED |`, 'Fired when the ads manager is done playing all the ads.');
|
||||||
|
this.handleEventListeners('ALL_ADS_COMPLETED');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.CLICK:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] CLICK |`, 'Fired when the ad is clicked.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.COMPLETE:
|
||||||
|
// This event indicates the ad has finished - the video player
|
||||||
|
// can perform appropriate UI actions, such as removing the timer for
|
||||||
|
// remaining time detection.
|
||||||
|
// clearInterval(intervalTimer);
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] COMPLETE |`, 'Fired when the ad completes playing.');
|
||||||
|
|
||||||
|
this.handleEventListeners('COMPLETE');
|
||||||
|
|
||||||
|
this.adDisplayElement.style.display = 'none';
|
||||||
|
|
||||||
|
if (this.player.currentTime < this.player.duration) {
|
||||||
|
this.player.play();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case window.google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] CONTENT_PAUSE_REQUESTED |`, 'Fired when content should be paused. This usually happens right before an ad is about to cover the content.');
|
||||||
|
|
||||||
|
this.handleEventListeners('CONTENT_PAUSE_REQUESTED');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case window.google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] CONTENT_RESUME_REQUESTED |`, 'Fired when content should be resumed. This usually happens when an ad finishes or collapses.');
|
||||||
|
|
||||||
|
this.handleEventListeners('CONTENT_RESUME_REQUESTED');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.LOADED:
|
||||||
// This is the first event sent for an ad - it is possible to
|
// This is the first event sent for an ad - it is possible to
|
||||||
// determine whether the ad is a video ad or an overlay.
|
// determine whether the ad is a video ad or an overlay.
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] LOADED |`, event.getAd().getContentType());
|
||||||
|
|
||||||
// Show the ad display element.
|
// Show the ad display element.
|
||||||
this.adDisplayElement.style.display = 'block';
|
this.adDisplayElement.style.display = 'block';
|
||||||
@ -141,59 +222,60 @@ export default class Ads {
|
|||||||
ad.width = container.offsetWidth;
|
ad.width = container.offsetWidth;
|
||||||
ad.height = container.offsetHeight;
|
ad.height = container.offsetHeight;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case window.google.ima.AdEvent.Type.STARTED:
|
// console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());
|
||||||
|
// console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.STARTED:
|
||||||
// This event indicates the ad has started - the video player
|
// This event indicates the ad has started - the video player
|
||||||
// can adjust the UI, for example display a pause button and
|
// can adjust the UI, for example display a pause button and
|
||||||
// remaining time.
|
// remaining time.
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] STARTED |`, 'Fired when the ad starts playing.');
|
||||||
|
|
||||||
this.player.pause();
|
this.player.pause();
|
||||||
this.handleEventListeners('STARTED');
|
this.handleEventListeners('STARTED');
|
||||||
|
|
||||||
// if (ad.isLinear()) {
|
|
||||||
// For a linear ad, a timer can be started to poll for
|
|
||||||
// the remaining time.
|
|
||||||
// intervalTimer = setInterval(
|
|
||||||
// () => {
|
|
||||||
// let remainingTime = this.adsManager.getRemainingTime();
|
|
||||||
// console.log(remainingTime);
|
|
||||||
// },
|
|
||||||
// 300); // every 300ms
|
|
||||||
// }
|
|
||||||
break;
|
break;
|
||||||
|
case google.ima.AdEvent.Type.DURATION_CHANGE:
|
||||||
case window.google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] DURATION_CHANGE |`, 'Fired when the ad\'s duration changes.');
|
||||||
this.handleEventListeners('CONTENT_PAUSE_REQUESTED');
|
|
||||||
break;
|
break;
|
||||||
|
case google.ima.AdEvent.Type.FIRST_QUARTILE:
|
||||||
case window.google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] FIRST_QUARTILE |`, 'Fired when the ad playhead crosses first quartile.');
|
||||||
this.handleEventListeners('CONTENT_RESUME_REQUESTED');
|
|
||||||
break;
|
break;
|
||||||
|
case google.ima.AdEvent.Type.IMPRESSION:
|
||||||
case window.google.ima.AdEvent.Type.AD_BREAK_READY:
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] IMPRESSION |`, 'Fired when the impression URL has been pinged.');
|
||||||
// This event indicates that a mid-roll ad is ready to start.
|
|
||||||
// We pause the player and tell the adsManager to start playing the ad.
|
|
||||||
this.player.pause();
|
|
||||||
this.adsManager.start();
|
|
||||||
this.handleEventListeners('AD_BREAK_READY');
|
|
||||||
break;
|
break;
|
||||||
|
case google.ima.AdEvent.Type.INTERACTION:
|
||||||
case window.google.ima.AdEvent.Type.COMPLETE:
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] INTERACTION |`, 'Fired when an ad triggers the interaction callback. Ad interactions contain an interaction ID string in the ad data.');
|
||||||
// This event indicates the ad has finished - the video player
|
|
||||||
// can perform appropriate UI actions, such as removing the timer for
|
|
||||||
// remaining time detection.
|
|
||||||
// clearInterval(intervalTimer);
|
|
||||||
this.handleEventListeners('COMPLETE');
|
|
||||||
|
|
||||||
this.adDisplayElement.style.display = 'none';
|
|
||||||
if (this.player.currentTime < this.player.duration) {
|
|
||||||
this.player.play();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
case google.ima.AdEvent.Type.LINEAR_CHANGED:
|
||||||
case window.google.ima.AdEvent.Type.ALL_ADS_COMPLETED:
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] LINEAR_CHANGED |`, 'Fired when the displayed ad changes from linear to nonlinear, or vice versa.');
|
||||||
this.handleEventListeners('ALL_ADS_COMPLETED');
|
break;
|
||||||
|
case google.ima.AdEvent.Type.MIDPOINT:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] MIDPOINT |`, 'Fired when the ad playhead crosses midpoint.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.PAUSED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] PAUSED |`, 'Fired when the ad is paused.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.RESUMED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] RESUMED |`, 'Fired when the ad is resumed.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.SKIPPABLE_STATE_CHANGED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] SKIPPABLE_STATE_CHANGED |`, 'Fired when the displayed ads skippable state is changed.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.SKIPPED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] SKIPPED |`, 'Fired when the ad is skipped by the user.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.THIRD_QUARTILE:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] THIRD_QUARTILE |`, 'Fired when the ad playhead crosses third quartile.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.USER_CLOSE:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] USER_CLOSE |`, 'Fired when the ad is closed by the user.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.VOLUME_CHANGED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] VOLUME_CHANGED |`, 'Fired when the ad volume has changed.');
|
||||||
|
break;
|
||||||
|
case google.ima.AdEvent.Type.VOLUME_MUTED:
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK] VOLUME_MUTED |`, 'Fired when the ad volume has been muted.');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -202,21 +284,44 @@ export default class Ads {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAdError(adErrorEvent) {
|
onAdError(adErrorEvent) {
|
||||||
// Handle the error logging.
|
this.cancel();
|
||||||
this.adDisplayElement.remove();
|
|
||||||
|
|
||||||
if (this.adsManager) {
|
|
||||||
this.adsManager.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.player.debug) {
|
if (this.player.debug) {
|
||||||
throw new Error(adErrorEvent);
|
throw new Error(adErrorEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the adsManager so we can grab new ads after this.
|
||||||
|
* If we don't then we're not allowed to call new ads based
|
||||||
|
* on google policies, as they interpret this as an accidental
|
||||||
|
* video requests. https://developers.google.com/interactive-
|
||||||
|
* media-ads/docs/sdks/android/faq#8
|
||||||
|
*/
|
||||||
|
cancel() {
|
||||||
|
this.player.debug.warn(`[${(Date.now() - this.time) / 1000}s][IMA SDK]`, 'Advertisement cancelled.');
|
||||||
|
|
||||||
|
// Todo: Removing the ad container might be problematic if we were to recreate the adsManager. Think of playlists. Every new video you need to request a new VAST xml and preload the advertisement.
|
||||||
|
this.adDisplayElement.remove();
|
||||||
|
|
||||||
|
// Tell our adsManager to go bye bye.
|
||||||
|
this.adsManagerPromise.then(() => {
|
||||||
|
if (this.adsManager) {
|
||||||
|
this.adsManager.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setupAdDisplayContainer() {
|
setupAdDisplayContainer() {
|
||||||
const { container } = this.player.elements;
|
const { container } = this.player.elements;
|
||||||
|
|
||||||
|
// So we can run VPAID2.
|
||||||
|
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);
|
||||||
|
|
||||||
|
// Set language.
|
||||||
|
// Todo: Could make a config option out of this locale value.
|
||||||
|
google.ima.settings.setLocale('en');
|
||||||
|
|
||||||
// We assume the adContainer is the video container of the plyr element
|
// We assume the adContainer is the video container of the plyr element
|
||||||
// that will house the ads.
|
// that will house the ads.
|
||||||
this.adDisplayContainer = new window.google.ima.AdDisplayContainer(container);
|
this.adDisplayContainer = new window.google.ima.AdDisplayContainer(container);
|
||||||
@ -230,32 +335,41 @@ export default class Ads {
|
|||||||
// Set class name on the adDisplayContainer element.
|
// Set class name on the adDisplayContainer element.
|
||||||
this.adDisplayElement.setAttribute('class', this.player.config.classNames.ads);
|
this.adDisplayElement.setAttribute('class', this.player.config.classNames.ads);
|
||||||
|
|
||||||
// Play ads when clicked.
|
// Play ads when clicked. Wait until the adsManager and adsLoader
|
||||||
this.setOnClickHandler(this.adDisplayElement, this.playAds);
|
// are both resolved.
|
||||||
|
Promise.all([
|
||||||
|
this.adsManagerPromise,
|
||||||
|
this.adsLoaderPromise,
|
||||||
|
]).then(() => {
|
||||||
|
this.setOnClickHandler(this.adDisplayElement, this.playAds);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
playAds() {
|
playAds() {
|
||||||
const { container } = this.player.elements;
|
const { container } = this.player.elements;
|
||||||
|
|
||||||
// Initialize the container. Must be done via a user action on mobile devices.
|
// Play the requested advertisement whenever the adsManager is ready.
|
||||||
this.adDisplayContainer.initialize();
|
this.adsManagerPromise.then(() => {
|
||||||
|
// Initialize the container. Must be done via a user action on mobile devices.
|
||||||
|
this.adDisplayContainer.initialize();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Initialize the ads manager. Ad rules playlist will start at this time.
|
// Initialize the ads manager. Ad rules playlist will start at this time.
|
||||||
this.adsManager.init(container.offsetWidth, container.offsetHeight, window.google.ima.ViewMode.NORMAL);
|
this.adsManager.init(container.offsetWidth, container.offsetHeight, window.google.ima.ViewMode.NORMAL);
|
||||||
|
|
||||||
// Call play to start showing the ad. Single video and overlay ads will
|
// Call play to start showing the ad. Single video and overlay ads will
|
||||||
// start at this time; the call will be ignored for ad rules.
|
// start at this time; the call will be ignored for ad rules.
|
||||||
this.adsManager.start();
|
this.adsManager.start();
|
||||||
} catch (adError) {
|
} catch (adError) {
|
||||||
// An error may be thrown if there was a problem with the VAST response.
|
// An error may be thrown if there was a problem with the VAST response.
|
||||||
this.player.play();
|
this.player.play();
|
||||||
this.adDisplayElement.remove();
|
this.adDisplayElement.remove();
|
||||||
|
|
||||||
if (this.player.debug) {
|
if (this.player.debug) {
|
||||||
throw new Error(adError);
|
throw new Error(adError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -314,7 +428,6 @@ export default class Ads {
|
|||||||
* @param {element} element - The element on which to set the listener
|
* @param {element} element - The element on which to set the listener
|
||||||
* @param {function} callback - The callback which will be invoked once triggered.
|
* @param {function} callback - The callback which will be invoked once triggered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
setOnClickHandler(element, callback) {
|
setOnClickHandler(element, callback) {
|
||||||
for (let i = 0; i < this.startEvents.length; i += 1) {
|
for (let i = 0; i < this.startEvents.length; i += 1) {
|
||||||
const startEvent = this.startEvents[i];
|
const startEvent = this.startEvents[i];
|
||||||
@ -339,4 +452,36 @@ export default class Ads {
|
|||||||
this.events[event] = callback;
|
this.events[event] = callback;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* startSafetyTimer
|
||||||
|
* Setup a safety timer for when the ad network
|
||||||
|
* doesn't respond for whatever reason. The advertisement has 12 seconds
|
||||||
|
* to get its shit together. We stop this timer when the advertisement
|
||||||
|
* is playing, or when a user action is required to start, then we
|
||||||
|
* clear the timer on ad ready.
|
||||||
|
* @param {Number} time
|
||||||
|
* @param {String} from
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
startSafetyTimer(time, from) {
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK]`, `Safety timer invoked timer from: ${from}`);
|
||||||
|
this.safetyTimer = window.setTimeout(() => {
|
||||||
|
this.cancel();
|
||||||
|
this.clearSafetyTimer('startSafetyTimer()');
|
||||||
|
}, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clearSafetyTimer
|
||||||
|
* @param {String} from
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
clearSafetyTimer(from) {
|
||||||
|
if (typeof this.safetyTimer !== 'undefined' && this.safetyTimer !== null) {
|
||||||
|
this.player.debug.log(`[${(Date.now() - this.time) / 1000}s][IMA SDK]`, `Safety timer cleared timer from: ${from}`);
|
||||||
|
clearTimeout(this.safetyTimer);
|
||||||
|
this.safetyTimer = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user