Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check if ima client side version is included #2

Merged
merged 1 commit into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# video-ad-manager-ima-wrapper

> Wrapper for HTML5 Video Ad Manager and IMA SDK to automatically switch GAM tags to use IMA SDK.
> Wrapper for [HTML5 Video Ad Manager](https://github.com/basil79/ads-manager) and [IMA SDK for HTML5](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side) to automatically switch [Google VAST ad tag](https://support.google.com/admanager/answer/10678356?hl=en) to use IMA SDK.

This SDK includes 2 video ad managers:

- [HTML5 Video Ad Manager](https://github.com/basil79/ads-manager)
- [IMA SDK for HTML5](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side)

NOTE: If you have already included the [ima3.js](https://imasdk.googleapis.com/js/sdkloader/ima3.js) script, the SDK will check the IMA SDK Client Side version if it was included and use it, if not, the SDK will try to load `ima3.js`.

**Table of Contents**

Expand Down
7 changes: 5 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@ <h3>Ad Events:</h3>
<br/>
<br/>

<script src="js/ads-manager-ima-wrapper.js?v=14"></script>
<script src="js/index.js?v=20"></script>
<!-- IMA SDK -->
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>

<script src="js/video-ad-manager-ima-wrapper.js?v=1"></script>
<script src="js/index.js?v=1"></script>


<br/>
Expand Down
330 changes: 330 additions & 0 deletions public/js/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,330 @@
(function() {

var playContentButton = document.getElementById('play-content-button');
var testAdButton = document.getElementById('test-ad-button');

var pauseAdButton = document.getElementById('pause-ad-button');
// var resumeAdButton = document.getElementById('resume-ad-button');
var stopAdButton = document.getElementById('stop-ad-button');
var skipAdButton = document.getElementById('skip-ad-button');
var resizeAdButton = document.getElementById('resize-ad-button');

function enableAdButtons() {
console.log('enable ad buttons');
var buttons = document.getElementsByClassName('ad-button');
for(var button of buttons) {
button.removeAttribute('disabled');
}
}
function disableAdButtons() {
console.log('disable ad buttons');
var buttons = document.getElementsByClassName('ad-button');
for(var button of buttons) {
button.setAttribute('disabled', true);
}
}

var clearLogsButton = document.getElementById('clear-logs-button');

// Events list
var eventsList = document.getElementById('events-list');
function appendEvent(text) {
var today = new Date();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds() + ":" + today.getMilliseconds();
var eventItem = document.createElement('li');
eventItem.innerHTML = time + ' ' + text;
eventsList.appendChild(eventItem);
}
function clearEvents() {
eventsList.innerHTML = '';
}

// Example
var videoElement = document.getElementById('video-element');
var adContainer = document.getElementById('ad-container');
var adsManager = new adserve.tv.VideoAdManagerIMAWrapper(adContainer, videoElement);

console.log('VideoAdManagerIMAWrapper version is', adsManager.getVersion());

var isAdPaused = false;

// Subscribe for events
adsManager.addEventListener('AdError', function(adError) {

console.log('AdError', adError);
console.log('AdError -> typeof', typeof adError);
if(typeof adError === 'object') {
console.log('AdError Message', adError.getMessage());
}

appendEvent('AdError : ' + adError);

if(adsManager) {
// Removes ad assets loaded at runtime that need to be properly removed at the time of ad completion
// and stops the ad and all tracking.
adsManager.abort();
}

isAdPaused = false;
if(videoElement.paused) {
videoElement.play();
}

disableAdButtons();
});
adsManager.addEventListener('AdsManagerLoaded', function() {
console.log('AdsManagerLoaded');
appendEvent('AdsManagerLoaded');
console.log('ads manager loaded');

var width = videoElement.clientWidth;
var height = videoElement.clientHeight;
var viewMode = 'normal'; // fullscreen

try {
adsManager.init(width, height, viewMode);
} catch (adError) {
// Play the video without ads, if an error occurs
console.log("AdsManager could not initialize ad");
}

});
adsManager.addEventListener('AdLoaded', function(adEvent) {
console.log('AdLoaded > ad type is', adEvent.type);
appendEvent('AdLoaded');
if(adEvent.type === 'linear') {
try {
adsManager.start();
} catch (adError) {
// Play the video without ads, if an error occurs
console.log("AdsManager could not be started");
}
} else {
console.log('ADM > AdLoaded > ad is not linear');
}
});
adsManager.addEventListener('AdStarted', function() {
console.log('AdStarted');
appendEvent('AdStarted');

// Pause
console.log('CONTENT_PAUSE_REQUESTED > is video not paused?', !videoElement.paused)
if(!videoElement.paused) {
videoElement.pause();
}

enableAdButtons();
});
adsManager.addEventListener('AdDurationChange', function() {
console.log('AdDurationChange');
console.log('getDuration >', adsManager.getDuration());
appendEvent('AdDurationChange');
});
adsManager.addEventListener('AdSizeChange', function() {
console.log('AdSizeChange');
appendEvent('AdSizeChange');
});
adsManager.addEventListener('AdVideoStart', function() {
console.log('AdVideoStart');
appendEvent('AdVideoStart');
});
adsManager.addEventListener('AdImpression', function() {
console.log('AdImpression');
appendEvent('AdImpression');
});
adsManager.addEventListener('AdVideoFirstQuartile', function() {
console.log('AdVideoFirstQuartile');
appendEvent('AdVideoFirstQuartile');
});
adsManager.addEventListener('AdVideoMidpoint', function() {
console.log('AdVideoMidpoint');
appendEvent('AdVideoMidpoint');
});
adsManager.addEventListener('AdVideoThirdQuartile', function() {
console.log('AdVideoThirdQuartile');
appendEvent('AdVideoThirdQuartile');
});
adsManager.addEventListener('AdPaused', function() {
console.log('AdPaused');
isAdPaused = true;
pauseAdButton.innerHTML = 'Resume Ad';
appendEvent('AdPaused');
});
adsManager.addEventListener('AdPlaying', function() {
console.log('AdPlaying');
isAdPaused = false;
pauseAdButton.innerHTML = 'Pause Ad';
appendEvent('AdPlaying');
});
adsManager.addEventListener('AdVideoComplete', function () {
console.log('AdVideoComplete');
appendEvent('AdVideoComplete');
});
adsManager.addEventListener('AdStopped', function () {
console.log('AdStopped');
appendEvent('AdStopped');
});
adsManager.addEventListener('AdSkipped', function() {
console.log('AdSkipped');
appendEvent('AdSkipped');
});
adsManager.addEventListener('AdClickThru', function(url, id) {
console.log('AdClickThru', url);
appendEvent('AdClickThru');
});
adsManager.addEventListener('AllAdsCompleted', async function () {
console.log('AllAdsCompleted');
appendEvent('AllAdsCompleted');
isAdPaused = false;

console.log('CONTENT_RESUME_REQUESTED')
// Resume player
if(!videoElement.ended) {
videoElement.play();

//console.log('set timeout of 5000, after ad complete and request ad again');
//setTimeout(requestAd, 5000);
}

disableAdButtons();
});

// Ad Request
//var vastUrl = 'http://v.adserve.tv/test/sample.xml';
//var vastUrl = 'http://v.adserve.tv/test/wrapper-multiple-ads.xml';
//var vastUrl = 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinearvpaid2js&correlator=';
var vastUrl = 'https://v.adserve.tv/pg/vast-vpaid.xml';
//var vastUrl = 'https://vid.springserve.com/vast/184920?ima=$[sps_ima_mode]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&widgetid=$[widgetId]&lob=$[abc]&clipid=$[clipId]&key_custom1=^w=$[widgetId]^c=$[clipId]^i=$[clipPlayCounter]^ab=$[abc]^v=$[v]^p=$[publisherId]&key_custom2=^d=$[domain]^u=$[utm]^dv=$[device]^co=$[geo]^pl=$[playback_type]&gdpr=$[gdpr]&consent=$[cd]&viewability=$[v]&schain=$[schain]&us_privacy=$[us_privacy]&domain=$[domain]&key_custom3=$[cma1]';
//var vastUrl = 'http://v.adserve.tv/pg/vast.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]'; //'http://localhost:3100/ads/pg/vast.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]';
//var vastUrl = 'https://vid.springserve.com/vast-xml/247996?id=184920&a_cc=s.184920-d.247996-cv.1025&w=640&h=360&d=demo.anyclip.com&url=http%3A%2F%2Fdemo.anyclip.com%2FLuminousX%2FTestPage.html&ssid=5937c6fd-4be6-4781-b42e-e9a31c91eef9.1597672072856&uuid=4349b3fb-4108-493a-907d-c6ceca437a8f&url=http%3A%2F%2Fdemo.anyclip.com%2FLuminousX%2FTestPage.html&_rcc=en.20954_vp.20247&_vlurl=http%3A%2F%2Fwww.anyclip.com%2F';
//var vastUrl = 'https://vid.springserve.com/vast/184920?ima=1&w=640&h=360&url=http%3A%2F%2Fdemo.anyclip.com%2FLuminousX%2FTestPage.html&cb=129511830&widgetid=demo_efi&lob=&clipid=my2hs5dygnvueqsrob5dmy2rpbdge5tc&key_custom1=^w=demo_efi^c=my2hs5dygnvueqsrob5dmy2rpbdge5tc^i=1^ab=^v=1^p=lre_demo_page&key_custom2=^d=demo.anyclip.com^u=^dv=1^co=IL^pl=a&gdpr=&consent=&viewability=1&schain=1.0,1!anyclip.com,001w000001fC68UAAS,1,,,,&us_privacy=&domain=demo.anyclip.com';
//var vastUrl = 'https://vid.springserve.com/vast/412415?w=$[w]&h=$[h]&url=$[url]&cb=$[cb]&pid=$[pid]&cid=$[cid]&wid=$[wid]&ip=$[ip]&ua=$[ua]&dom=$[dom]&abtest=$[abc]';
//var vastUrl = 'https://vid.springserve.com/vast-xml/243952?id=412415&a_cc=s.412415-d.243952-cv.1011&url=%24%5Burl%5D&ua=%24%5Bua%5D&ssid=3a865307-ac69-42b7-9ea7-087889c9345c.1625055605015&uuid=db9cc521-a0db-4607-8b61-f381e99f89bb&url=%24%5Burl%5D&_rcc=en.22277_vp.22315&_vlurl=http%3A%2F%2Fanyclip.com';
//var vastUrl = 'http://v.adserve.tv/test/wrapper-a.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]'; //'http://localhost:3100/ads/test/wrapper-a.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]';
//var vastUrl = 'http://v.adserve.tv/test/empty-no-ad.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]'; //'http://localhost:3100/ads/test/empty-no-ad.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]';
//var vastUrl = 'http://v.adserve.tv/test/empty-no-creative.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]'; //'http://localhost:3100/ads/test/empty-no-creative.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]';
//var vastUrl = 'http://v.adserve.tv/test/inline-linear.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]'; //'http://localhost:3100/ads/test/inline-linear.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]';
//var vastUrl = 'http://v.adserve.tv/test/wrapper-ad-pod.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]'; //'http://localhost:3100/ads/test/wrapper-ad-pod.xml?ip=$[ip]&w=$[width]&h=$[height]&url=$[pageUrl]&cb=$[cb]&origin_url=$[originUrl]';


// TODO:
/*
videoElement.muted = true;
videoElement.load();
videoElement.play();
*/

window.addEventListener('resize', function(event) {
console.log("window resized");
var width = videoElement.clientWidth;
var height = videoElement.clientHeight;
var viewMode = 'normal';
adsManager.resize(width, height, viewMode);
});

/*
// Request ads
console.log('ad request');

// Test VAST XML instead of VAST URL
var vastXML = `<?xml version="1.0" encoding="UTF-8"?>
<VAST version="2.0">
<Error><![CDATA[http://example.com/empty-no-ad]]></Error>
</VAST>`;
//adsManager.requestAds(vastXML);

adsManager.requestAds(vastUrl);
*/

/*
setInterval(function() {
console.log('ad request');
adsManager.requestAds(vastUrl);
}, 10000);
*/



playContentButton.addEventListener('click', function(event) {
console.log('play content');

videoElement.play();
requestAd();
/*
var playPromise = videoElement.play();
if(playPromise !== undefined) {
playPromise.then(_ => {
// Automatic playback started!
// Show playing UI.
console.log('playback started');
//videoElement.pause();
//videoElement.load();
return requestAd();
}).catch(error => {
// Auto-play was prevented
// Show paused UI.
console.log('prevented')
});
}
*/
}, false);


function requestAd() {

console.log('request ad');

isAdPaused = false;
pauseAdButton.innerHTML = 'Pause Ad';

// Clear events
clearEvents();

var giveVastUrl = document.getElementById('vast-url-input').value;

if(videoElement.paused) {
videoElement.play();
}

adsManager.requestAds(giveVastUrl, { muted: false });
}

testAdButton.addEventListener('click', function() {
console.log('test button click');
videoElement.muted = true;
requestAd();
}, false);

pauseAdButton.addEventListener('click', function(event) {
if(!isAdPaused) {
adsManager.pause();
} else {
adsManager.resume();
}
}, false);
/*
resumeAdButton.addEventListener('click', function() {
adsManager.resume();
}, false);
*/
stopAdButton.addEventListener('click', function() {
adsManager.stop();
}, false);

skipAdButton.addEventListener('click', function() {
adsManager.skip();
}, false);

resizeAdButton.addEventListener('click', function() {
var width = videoElement.clientWidth;
var height = videoElement.clientHeight;
var viewMode = 'normal';
adsManager.resize(width, height, viewMode);
}, false);

clearLogsButton.addEventListener('click', function() {
// Clear events
clearEvents();
}, false);

})()
4 changes: 2 additions & 2 deletions public/js/video-ad-manager-ima-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var adserve;
\**********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"tv\": () => (/* binding */ tv)\n/* harmony export */ });\n/* harmony import */ var _video_ad_manager_ima_wrapper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./video-ad-manager-ima-wrapper */ \"./src/video-ad-manager-ima-wrapper.js\");\n\n\nconst tv = {\n VideoAdManagerImaWrapper: _video_ad_manager_ima_wrapper__WEBPACK_IMPORTED_MODULE_0__[\"default\"]\n}\n\n\n\n\n//# sourceURL=webpack://adserve/./src/index.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"tv\": () => (/* binding */ tv)\n/* harmony export */ });\n/* harmony import */ var _video_ad_manager_ima_wrapper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./video-ad-manager-ima-wrapper */ \"./src/video-ad-manager-ima-wrapper.js\");\n\n\nconst tv = {\n VideoAdManagerIMAWrapper: _video_ad_manager_ima_wrapper__WEBPACK_IMPORTED_MODULE_0__[\"default\"]\n}\n\n\n\n\n//# sourceURL=webpack://adserve/./src/index.js?");

/***/ }),

Expand All @@ -31,7 +31,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
\*********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst VideoAdManagerImaWrapper = function() {\n // TODO:\n this._options = {};\n};\nVideoAdManagerImaWrapper.prototype.requestAds = (vastUrl, options = {}) => {\n console.log('request ads');\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (VideoAdManagerImaWrapper);\n\n\n//# sourceURL=webpack://adserve/./src/video-ad-manager-ima-wrapper.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst VideoAdManagerIMAWrapper = function(adContainer, videoElement) {\n\n if(!(adContainer instanceof Element || adContainer instanceof HTMLDocument) || !(videoElement instanceof Element || videoElement instanceof HTMLDocument)) {\n throw new Error('ad container and/or video element are not defined');\n }\n\n this._adContainer = null;\n this._videoElement = null;\n\n this._attributes = {\n width: 300,\n height: 154,\n viewMode: 'normal',\n volume: 0,\n version: '1.0.0'\n };\n this._eventCallbacks = {};\n\n this.IMA_SDK_URL = 'https://imasdk.googleapis.com/js/sdkloader/ima3.js';\n\n this._adsManager = null; // TODO\n this._imaManager = null; // TODO\n\n\n this.initAdsManager();\n this.initIMAManager();\n\n};\nVideoAdManagerIMAWrapper.prototype.init = function(width, height, viewMode) {\n console.log('init');\n};\n// TODO:\nVideoAdManagerIMAWrapper.prototype.initAdsManager = function() {\n console.log('init ads manager');\n};\nVideoAdManagerIMAWrapper.prototype.initIMAManager = function() {\n console.log('init ima');\n // Check that Client Side IMA SDK has been included\n // NOTE: (window['google'] && google.ima) check for any\n // IMA SDK, including SDK for Server Side ads.\n // The 3rd check insures we have the right SDK:\n // {google.ima.AdsLoader} is an object that's part of Client Side IMA SDK\n // but not Server Side SDK.\n if (!window['google'] || !google.ima || !google.ima.AdsLoader) {\n console.log('ima3.js is not included');\n } else {\n console.log('ima3.js is included, use it');\n }\n};\n\nVideoAdManagerIMAWrapper.prototype.requestAds = function(vastUrl, options = {}) {\n console.log('request ads', vastUrl);\n};\nVideoAdManagerIMAWrapper.prototype.resize = function(width, height, viewMode) {\n // TODO:\n};\nVideoAdManagerIMAWrapper.prototype.addEventListener = function(eventName, callback, context) {\n const givenCallback = callback.bind(context);\n this._eventCallbacks[eventName] = givenCallback;\n};\nVideoAdManagerIMAWrapper.prototype.removeEventListener = function(eventName) {\n this._eventCallbacks[eventName] = null;\n};\nVideoAdManagerIMAWrapper.removeEventListeners = function(eventCallbacks) {\n for (const eventName in eventCallbacks) {\n eventCallbacks.hasOwnProperty(eventName) && this.removeEventListener(eventName);\n }\n};\nVideoAdManagerIMAWrapper.prototype.getVersion = function() {\n return this._attributes.version;\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (VideoAdManagerIMAWrapper);\n\n\n//# sourceURL=webpack://adserve/./src/video-ad-manager-ima-wrapper.js?");

/***/ })

Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import VideoAdManagerImaWrapper from './video-ad-manager-ima-wrapper';
import VideoAdManagerIMAWrapper from './video-ad-manager-ima-wrapper';

const tv = {
VideoAdManagerImaWrapper
VideoAdManagerIMAWrapper
}

export { tv }
Loading