Ads improvements for volume and race condition fix
This commit is contained in:
parent
9b81e776fb
commit
a1b2c0419f
@ -14,6 +14,20 @@ import loadScript from '../utils/loadScript';
|
|||||||
import { formatTime } from '../utils/time';
|
import { formatTime } from '../utils/time';
|
||||||
import { buildUrlParams } from '../utils/urls';
|
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 {
|
class Ads {
|
||||||
/**
|
/**
|
||||||
* Ads constructor.
|
* Ads constructor.
|
||||||
@ -63,20 +77,22 @@ class Ads {
|
|||||||
* Load the IMA SDK
|
* Load the IMA SDK
|
||||||
*/
|
*/
|
||||||
load() {
|
load() {
|
||||||
if (this.enabled) {
|
if (!this.enabled) {
|
||||||
// Check if the Google IMA3 SDK is loaded or load it ourselves
|
return;
|
||||||
if (!is.object(window.google) || !is.object(window.google.ima)) {
|
}
|
||||||
loadScript(this.player.config.urls.googleIMA.sdk)
|
|
||||||
.then(() => {
|
// Check if the Google IMA3 SDK is loaded or load it ourselves
|
||||||
this.ready();
|
if (!is.object(window.google) || !is.object(window.google.ima)) {
|
||||||
})
|
loadScript(this.player.config.urls.googleIMA.sdk)
|
||||||
.catch(() => {
|
.then(() => {
|
||||||
// Script failed to load or is blocked
|
this.ready();
|
||||||
this.trigger('error', new Error('Google IMA SDK failed to load'));
|
})
|
||||||
});
|
.catch(() => {
|
||||||
} else {
|
// Script failed to load or is blocked
|
||||||
this.ready();
|
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
|
* Get the ads instance ready
|
||||||
*/
|
*/
|
||||||
ready() {
|
ready() {
|
||||||
|
// Double check we're enabled
|
||||||
|
if (!this.enabled) {
|
||||||
|
destroy(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Start ticking our safety timer. If the whole advertisement
|
// Start ticking our safety timer. If the whole advertisement
|
||||||
// thing doesn't resolve within our set time; we bail
|
// thing doesn't resolve within our set time; we bail
|
||||||
this.startSafetyTimer(12000, 'ready()');
|
this.startSafetyTimer(12000, 'ready()');
|
||||||
@ -240,9 +261,6 @@ class Ads {
|
|||||||
// Get the cue points for any mid-rolls by filtering out the pre- and post-roll
|
// Get the cue points for any mid-rolls by filtering out the pre- and post-roll
|
||||||
this.cuePoints = this.manager.getCuePoints();
|
this.cuePoints = this.manager.getCuePoints();
|
||||||
|
|
||||||
// Set volume to match player
|
|
||||||
this.manager.setVolume(this.player.volume);
|
|
||||||
|
|
||||||
// Add listeners to the required events
|
// Add listeners to the required events
|
||||||
// Advertisement error events
|
// Advertisement error events
|
||||||
this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));
|
this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));
|
||||||
@ -297,15 +315,15 @@ class Ads {
|
|||||||
triggerEvent.call(this.player, this.player.media, event);
|
triggerEvent.call(this.player, this.player.media, event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Bubble the event
|
||||||
|
dispatchEvent(event.type);
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case google.ima.AdEvent.Type.LOADED:
|
case google.ima.AdEvent.Type.LOADED:
|
||||||
// This is the first event sent for an ad - it is possible to determine whether the
|
// This is the first event sent for an ad - it is possible to determine whether the
|
||||||
// ad is a video ad or an overlay
|
// ad is a video ad or an overlay
|
||||||
this.trigger('loaded');
|
this.trigger('loaded');
|
||||||
|
|
||||||
// Bubble event
|
|
||||||
dispatchEvent(event.type);
|
|
||||||
|
|
||||||
// Start countdown
|
// Start countdown
|
||||||
this.pollCountdown(true);
|
this.pollCountdown(true);
|
||||||
|
|
||||||
@ -317,15 +335,19 @@ class Ads {
|
|||||||
|
|
||||||
// console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());
|
// console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());
|
||||||
// console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());
|
// 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;
|
break;
|
||||||
|
|
||||||
case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:
|
case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:
|
||||||
// All ads for the current videos are done. We can now request new advertisements
|
// All ads for the current videos are done. We can now request new advertisements
|
||||||
// in case the video is re-played
|
// 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.
|
// 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.
|
// So here we load a new video when all ads are done.
|
||||||
// Then we load new ads within a new adsManager. When the video
|
// Then we load new ads within a new adsManager. When the video
|
||||||
@ -350,6 +372,7 @@ class Ads {
|
|||||||
// playing when the IMA SDK is ready or has failed
|
// playing when the IMA SDK is ready or has failed
|
||||||
|
|
||||||
this.loadAds();
|
this.loadAds();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:
|
case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:
|
||||||
@ -357,8 +380,6 @@ class Ads {
|
|||||||
// for example display a pause button and remaining time. Fired when content should
|
// 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
|
// be paused. This usually happens right before an ad is about to cover the content
|
||||||
|
|
||||||
dispatchEvent(event.type);
|
|
||||||
|
|
||||||
this.pauseContent();
|
this.pauseContent();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -369,26 +390,17 @@ class Ads {
|
|||||||
// Fired when content should be resumed. This usually happens when an ad finishes
|
// Fired when content should be resumed. This usually happens when an ad finishes
|
||||||
// or collapses
|
// or collapses
|
||||||
|
|
||||||
dispatchEvent(event.type);
|
|
||||||
|
|
||||||
this.pollCountdown();
|
this.pollCountdown();
|
||||||
|
|
||||||
this.resumeContent();
|
this.resumeContent();
|
||||||
|
|
||||||
break;
|
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:
|
case google.ima.AdEvent.Type.LOG:
|
||||||
if (adData.adError) {
|
if (adData.adError) {
|
||||||
this.player.debug.warn(`Non-fatal ad error: ${adData.adError.getMessage()}`);
|
this.player.debug.warn(`Non-fatal ad error: ${adData.adError.getMessage()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -463,6 +475,9 @@ class Ads {
|
|||||||
// Play the requested advertisement whenever the adsManager is ready
|
// Play the requested advertisement whenever the adsManager is ready
|
||||||
this.managerPromise
|
this.managerPromise
|
||||||
.then(() => {
|
.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
|
// Initialize the container. Must be done via a user action on mobile devices
|
||||||
this.elements.displayContainer.initialize();
|
this.elements.displayContainer.initialize();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user