diff options
author | Sam Potts <sam@potts.es> | 2019-06-01 19:55:14 +1000 |
---|---|---|
committer | Sam Potts <sam@potts.es> | 2019-06-01 19:55:14 +1000 |
commit | 12c6282d14e3e06a7784760f83affc9195afed1f (patch) | |
tree | af1c6be692c4cf2679e7efc604896b686974368d /src/js/plugins/ads.js | |
parent | 996075decc6e8c0f0c5059dccea21b16020eb78b (diff) | |
parent | 0249772f019762ebd494ac409e597103820413c3 (diff) | |
download | plyr-12c6282d14e3e06a7784760f83affc9195afed1f.tar.lz plyr-12c6282d14e3e06a7784760f83affc9195afed1f.tar.xz plyr-12c6282d14e3e06a7784760f83affc9195afed1f.zip |
Merge branch 'develop' into css-variables
# Conflicts:
# .eslintrc
# demo/dist/demo.css
# demo/dist/demo.js
# demo/dist/demo.min.js
# demo/dist/demo.min.js.map
# dist/plyr.css
# dist/plyr.js
# dist/plyr.min.js
# dist/plyr.min.js.map
# dist/plyr.min.mjs
# dist/plyr.min.mjs.map
# dist/plyr.mjs
# dist/plyr.polyfilled.js
# dist/plyr.polyfilled.min.js
# dist/plyr.polyfilled.min.js.map
# dist/plyr.polyfilled.min.mjs
# dist/plyr.polyfilled.min.mjs.map
# dist/plyr.polyfilled.mjs
# gulpfile.js
# package.json
Diffstat (limited to 'src/js/plugins/ads.js')
-rw-r--r-- | src/js/plugins/ads.js | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/src/js/plugins/ads.js b/src/js/plugins/ads.js index c9256b0e..e6fab967 100644 --- a/src/js/plugins/ads.js +++ b/src/js/plugins/ads.js @@ -14,6 +14,20 @@ import loadScript from '../utils/loadScript'; import { formatTime } from '../utils/time'; import { buildUrlParams } from '../utils/urls'; +const destroy = instance => { + // Destroy our adsManager + if (instance.manager) { + instance.manager.destroy(); + } + + // Destroy our adsManager + if (instance.elements.displayContainer) { + instance.elements.displayContainer.destroy(); + } + + instance.elements.container.remove(); +}; + class Ads { /** * Ads constructor. @@ -63,20 +77,22 @@ class Ads { * Load the IMA SDK */ load() { - if (this.enabled) { - // Check if the Google IMA3 SDK is loaded or load it ourselves - if (!is.object(window.google) || !is.object(window.google.ima)) { - loadScript(this.player.config.urls.googleIMA.sdk) - .then(() => { - this.ready(); - }) - .catch(() => { - // Script failed to load or is blocked - this.trigger('error', new Error('Google IMA SDK failed to load')); - }); - } else { - this.ready(); - } + if (!this.enabled) { + return; + } + + // Check if the Google IMA3 SDK is loaded or load it ourselves + if (!is.object(window.google) || !is.object(window.google.ima)) { + loadScript(this.player.config.urls.googleIMA.sdk) + .then(() => { + this.ready(); + }) + .catch(() => { + // Script failed to load or is blocked + this.trigger('error', new Error('Google IMA SDK failed to load')); + }); + } else { + this.ready(); } } @@ -84,6 +100,11 @@ class Ads { * Get the ads instance ready */ ready() { + // Double check we're enabled + if (!this.enabled) { + destroy(this); + } + // Start ticking our safety timer. If the whole advertisement // thing doesn't resolve within our set time; we bail this.startSafetyTimer(12000, 'ready()'); @@ -240,16 +261,13 @@ class Ads { // Get the cue points for any mid-rolls by filtering out the pre- and post-roll this.cuePoints = this.manager.getCuePoints(); - // Set volume to match player - this.manager.setVolume(this.player.volume); - // Add listeners to the required events // Advertisement error events this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error)); // Advertisement regular events Object.keys(google.ima.AdEvent.Type).forEach(type => { - this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event)); + this.manager.addEventListener(google.ima.AdEvent.Type[type], e => this.onAdEvent(e)); }); // Resolve our adsManager @@ -285,7 +303,6 @@ class Ads { */ onAdEvent(event) { const { container } = this.player.elements; - // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED) // don't have ad object associated const ad = event.getAd(); @@ -293,19 +310,18 @@ class Ads { // Proxy event const dispatchEvent = type => { - const event = `ads${type.replace(/_/g, '').toLowerCase()}`; - triggerEvent.call(this.player, this.player.media, event); + triggerEvent.call(this.player, this.player.media, `ads${type.replace(/_/g, '').toLowerCase()}`); }; + // Bubble the event + dispatchEvent(event.type); + switch (event.type) { case google.ima.AdEvent.Type.LOADED: // This is the first event sent for an ad - it is possible to determine whether the // ad is a video ad or an overlay this.trigger('loaded'); - // Bubble event - dispatchEvent(event.type); - // Start countdown this.pollCountdown(true); @@ -317,15 +333,19 @@ class Ads { // console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex()); // console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset()); + + break; + + case google.ima.AdEvent.Type.STARTED: + // Set volume to match player + this.manager.setVolume(this.player.volume); + break; case google.ima.AdEvent.Type.ALL_ADS_COMPLETED: // All ads for the current videos are done. We can now request new advertisements // in case the video is re-played - // Fire event - dispatchEvent(event.type); - // TODO: Example for what happens when a next video in a playlist would be loaded. // So here we load a new video when all ads are done. // Then we load new ads within a new adsManager. When the video @@ -350,6 +370,7 @@ class Ads { // playing when the IMA SDK is ready or has failed this.loadAds(); + break; case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED: @@ -357,8 +378,6 @@ class Ads { // for example display a pause button and remaining time. Fired when content should // be paused. This usually happens right before an ad is about to cover the content - dispatchEvent(event.type); - this.pauseContent(); break; @@ -369,26 +388,17 @@ class Ads { // Fired when content should be resumed. This usually happens when an ad finishes // or collapses - dispatchEvent(event.type); - this.pollCountdown(); this.resumeContent(); break; - case google.ima.AdEvent.Type.STARTED: - case google.ima.AdEvent.Type.MIDPOINT: - case google.ima.AdEvent.Type.COMPLETE: - case google.ima.AdEvent.Type.IMPRESSION: - case google.ima.AdEvent.Type.CLICK: - dispatchEvent(event.type); - break; - case google.ima.AdEvent.Type.LOG: if (adData.adError) { this.player.debug.warn(`Non-fatal ad error: ${adData.adError.getMessage()}`); } + break; default: @@ -463,6 +473,9 @@ class Ads { // Play the requested advertisement whenever the adsManager is ready this.managerPromise .then(() => { + // Set volume to match player + this.manager.setVolume(this.player.volume); + // Initialize the container. Must be done via a user action on mobile devices this.elements.displayContainer.initialize(); |