HTML5 IMA SDK - Requesting Fullslot & Overlay Ad

1,391 views
Skip to first unread message

Simon Ferndriger

unread,
Nov 23, 2016, 6:30:09 AM11/23/16
to Interactive Media Ads SDK
Hi


I'm trying to request both a fullslot and overlay ad for our self-made player.
The request happens at different times, but the only request, that returns an ad is the fullslot one. As for the overlay, I always get this:

Yd {h: "The VAST response document is empty.", g: 1009, l: "adLoadError"}

What needs to be done differently for the overlay in order for it to work?

This is the current code I use:

var google = google || { ima: 'blocked' }; //AdBlocker
/*
#################################################################
# #
# Required: Google IMA SDK for HTML5 #
# #
#################################################################
*/


wct.videoads = (function(){
'use strict';
//---------------------------------------------------------------
// AdBlocker
//---------------------------------------------------------------
if(google.ima == 'blocked')
return function(){};
//---------------------------------------------------------------
// $_
//---------------------------------------------------------------
var $_ = {
//SnigelWeb: AdX for Video Product (HTML5 Full-Slot Ads)
};

//---------------------------------------------------------------
// _
//---------------------------------------------------------------
var _ = {
adsManagerOverlay: { destroy: function(){}, resize: function(){} },
adsManagerPostRoll: { destroy: function(){}, resize: function(){} },
height: 0,
onError: function(){},
width: 0
};

//---------------------------------------------------------------
// :
var createAds = function($container, width, height){
//---------------------------------------------------------------
_.height = height;
_.width = width;


//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
// Init
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
google.ima.settings.setLocale(LANGUAGE.id);
var adDisplayContainer = new google.ima.AdDisplayContainer($container.get(0));
adDisplayContainer.initialize();

var adsLoaderPostRoll = new google.ima.AdsLoader(adDisplayContainer);
var adsLoaderOverlay = new google.ima.AdsLoader(adDisplayContainer);
var postRollRequest = new google.ima.AdsRequest();
var overlayRequest = new google.ima.AdsRequest();

postRollRequest.adTagUrl = $_.adTagPostroll;
postRollRequest.linearAdSlotWidth = width;
postRollRequest.linearAdSlotHeight = height;
postRollRequest.nonLinearAdSlotWidth = width;
postRollRequest.nonLinearAdSlotHeight = height;
postRollRequest.forceNonLinearFullSlot = true;
overlayRequest.adTagUrl = $_.adTagOverlay;
overlayRequest.linearAdSlotWidth = width;
overlayRequest.linearAdSlotHeight = height;
overlayRequest.nonLinearAdSlotWidth = width;
overlayRequest.nonLinearAdSlotHeight = height;
overlayRequest.forceNonLinearFullSlot = false;


//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
// LOCAL Events
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
adsLoaderPostRoll.addEventListener(
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
onAdsManagerPostRollLoaded,
false
);
adsLoaderPostRoll.addEventListener(
google.ima.AdErrorEvent.Type.AD_ERROR,
onAdErrorPostRoll,
false
);
adsLoaderOverlay.addEventListener(
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
onAdsManagerOverlayLoaded,
false
);
adsLoaderOverlay.addEventListener(
google.ima.AdErrorEvent.Type.AD_ERROR,
onAdErrorOverlay,
false
);

//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
// :
var startOverlay = function(options){
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
var options = options || {};
adsLoaderOverlay.contentComplete();
adsLoaderOverlay.requestAds(overlayRequest);
_.onErrorOverlay = options.onEmpty || function(){};
};

//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
// :
var startPostRoll = function(details){
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
return;
_.onContentPauseRequested = details.onAdStart;
_.onContentResumeRequested = details.onAdFinish;
adsLoaderPostRoll.requestAds(postRollRequest);
_.onErrorPostRoll = details.onEmpty || function(){};
};

//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
// >
//¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
return {
startOverlay: startOverlay,
startPostRoll: startPostRoll,
resize: resize
};
};
//---------------------------------------------------------------
// :
var onAdErrorOverlay = function(adErrorEvent) {
//---------------------------------------------------------------
_.onErrorOverlay();
console.warn(adErrorEvent.getError());
// _.adsManagerOverlay.destroy();
};
//---------------------------------------------------------------
// :
var onAdErrorPostRoll = function(adErrorEvent) {
//---------------------------------------------------------------
_.onErrorPostRoll();
console.warn(adErrorEvent.getError());
// _.adsManagerPostRoll.destroy();
};

//---------------------------------------------------------------
// :
var onAdsManagerOverlayLoaded = function(adsManagerLoadedEvent){
//---------------------------------------------------------------
console.debug('overlay ad loaded:');
console.log(adsManagerLoadedEvent);
};
//---------------------------------------------------------------
// :
var onAdsManagerPostRollLoaded = function(adsManagerLoadedEvent){
//---------------------------------------------------------------
_.adsManagerPostRoll = adsManagerLoadedEvent.getAdsManager(document.createElement('video'));
_.adsManagerPostRoll.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, onAdError);
_.adsManagerPostRoll.addEventListener(google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, _.onContentPauseRequested);
_.adsManagerPostRoll.addEventListener(google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, _.onContentResumeRequested);
_.adsManagerPostRoll.addEventListener(google.ima.AdEvent.Type.LOADED, function(event){
});

try {
_.adsManagerPostRoll.init(_.width, _.height, google.ima.ViewMode[$(document).fullScreen() ? 'FULLSCREEN' : 'NORMAL']);

// Call start to show ads. Single video and overlay ads will
// start at this time; this call will be ignored for ad rules, as ad rules
// ads start when the adsManager is initialized.
_.adsManagerPostRoll.start();
}catch(adError){
console.error(adError);
}
};
//---------------------------------------------------------------
// :
var resize = function(width, height){
//---------------------------------------------------------------
_.adsManagerPostRoll.resize(width, height, google.ima.ViewMode[$(document).fullScreen() ? 'FULLSCREEN' : 'NORMAL']);
};
//---------------------------------------------------------------
// >
//---------------------------------------------------------------
return createAds;
}());





Thanks in advance!

Vu Chau (IMA SDK Team)

unread,
Nov 23, 2016, 11:27:07 AM11/23/16
to Interactive Media Ads SDK
Hi Simon,

As discussed in our Stack Overflow conversation, getting empty VAST responses is a serving issue, as opposed to SDK.  While you are getting your non-linear overlay tag sorted out, you can use our sample overlay tag against which to test your implementation. 

Assuming that our tag is returning a valid response for you, here is my proposed logic to request and play overlay and fullslot ads:

First, have separately defined variables for your overlay ad tag, and your fullslot ad tag.  Then, initialize the SDK.  To simplify things, let's use one adsLoader instance, and one adsManager instance for both ad types.

We first check if we have any previous adsManager instance in memory.  If so, we destroy it.  Also, call contentComplete() on the adsLoader so that the next ad request will not serve an empty VAST response.  The logic should look like this:
  if (adsManager != null) {
      console.log("adsManager is active. Destroying...");
      adsManager.destroy();
      adsLoader.contentComplete();
  }

  var adsRequest = new google.ima.AdsRequest();

  adsRequest.linearAdSlotWidth = 640;
  adsRequest.linearAdSlotHeight = 400;

  adsRequest.nonLinearAdSlotWidth = 640;
  adsRequest.nonLinearAdSlotHeight = 150;

  switch (adType) {
      case "overlay":
          adsRequest.adTagUrl = overlayTag;
          break;
      case "fullslot":
          adsRequest.adTagUrl = fullslotTag;
          adsRequest.forceNonLinearFullSlot = true;
          break;
  }

  adsLoader.requestAds(adsRequest);
I am sending my ad request based on user clicks, but you can do it based on other factors (such as timestamps, other events, etc.). I put together a live demo here.

Vu Chau
IMA SDK Team

Simon Ferndriger

unread,
Nov 24, 2016, 4:58:21 AM11/24/16
to Interactive Media Ads SDK
Hi Vu Chau


Thanks for the test VAST tag. At least now I get a new error:
Uncaught ReferenceError: ytcfg is not defined(…)


Seems that the demo tag is not working also?

Vu Chau (IMA SDK Team)

unread,
Nov 24, 2016, 8:49:05 AM11/24/16
to Interactive Media Ads SDK
Hi Simon,

That error shouldn't affect your ad playback, but we have a fix for it that should go live soon.

Let us know if the demo works for your use case.

Vu
Message has been deleted

Simon Ferndriger

unread,
Nov 25, 2016, 8:12:57 AM11/25/16
to Interactive Media Ads SDK
Awesome, with your test tag it really works! Thanks!

I have 3 follow up question:
1) How can I position the ad (it should be a bit higher)?
2) How can I make the ad closable?
3) How can I give the ad a transparent background which wills the lower part of the video?


Thanks in advance.


Best
Simon

Vu Chau (IMA SDK Team)

unread,
Nov 25, 2016, 10:17:49 PM11/25/16
to Interactive Media Ads SDK
Hi Simon,

Glad to hear you got it working! As for your questions:

1) How can I position the ad (it should be a bit higher)?
By default, non-linear overlays will always be rendered at the bottom of the video player screen.  To enable customization, you need to turn autoAlign on your adsRenderingSettings to false. By turning it to false, the SDK will render the nonlinear overlay at 0,0 of the adsContainer div, which means you have the freedom to position the div yourself.  The demo has been updated to reflect this so be sure to check out the new logic.
Right now, I'm actually using two adsContainer div's - one for the nonlinear, and one for everything else.  Once you start moving the nonlinear container around, if you use the same div for your fullslot or linear ad, the ad is going to look off (because we are moving the actual container rather than moving the nonlinear overlay image).  Having two adsContainer div's gives more flexibility.  
2) How can I make the ad closable?
You can set useStyledNonLinearAds on your adsRenderingSettings to true. With that setting, the ad will have a close and recall button. I have updated the demo to reflect the change. 

3) How can I give the ad a transparent background which wills the lower part of the video?
I'm not sure what you meant by this, so feel free to elaborate on this request.

Vu Chau
IMA SDK Team 
Message has been deleted

Simon Ferndriger

unread,
Nov 29, 2016, 9:29:19 AM11/29/16
to Interactive Media Ads SDK
Hi Vu Chau


Thanks!

Where can I see this demo you are referring to? It would be great to see how you set autoAlign and useStyledNonLinearAds.

3) The idea was to fill (not will) the background with a transparent color, lets say rgba(0,0,0,.5) of the bottom part of the video. This marks the bottom area and give the ad some space to "sit" on, rather than just "flying" around in the design. So it would look like this for example:



BTW: Why isn't it possible to edit posts?

Vu Chau (IMA SDK Team)

unread,
Nov 29, 2016, 10:14:28 AM11/29/16
to Interactive Media Ads SDK
Hi Simon,

All the new changes from the last post were updated in the same example (http://chauduyphanvu1.com/IMA_FullSlot_Overlay).  Check it out and let me know if you have any questions.

The SDK doesn't support transparent/opaque property for the ad slot, but you can easily set the corresponding CSS properties of the div that hosts the ad.  Alternatively, you can create a separate div with opacity < 1, and set its z-index to be lower than your ad slot.

Vu Chau
IMA SDK Team

Simon Ferndriger

unread,
Nov 29, 2016, 10:52:45 AM11/29/16
to Interactive Media Ads SDK
Hi Vu Chau


Thanks, this helps!
I think I got it now. When disabling autoAlign, it makes sense to create a separat google.ima.AdDisplayContainer for displaying the overlay.
So I guess, I cannot create two AdDisplayContainer at the same time (overlay and fullslot) to render the overlay now and the fullslot later?

Best
Simon

Vu Chau (IMA SDK Team)

unread,
Nov 29, 2016, 11:17:29 AM11/29/16
to Interactive Media Ads SDK
Hi Simon,

It is possible to render both the overlay and the fullslot ads in one container, but due to UI cosmetic reasons I opted for two containers so that I can individually position each on my page (so that they look as if they are one container overlaying the content video player).  What happens is that when autoAlign is turned off, the container will be positioned at 0,0 of your adsLoader.  Since the overlay ad will never take up the entire container, moving the ad is actually moving the container/div.  If you have other content/stuff/DOM elements that are located nearby the video player, the remainder of the container div (now that the 0,0 origin of it has been dragged somewhere else) will overlap them.  I have attached a screenshot for a visual representation.  

Without using a second container div for my fullslot ad, since the old div has been moved away from the initial 0,0, the fullslot ad will overlap content nearby the video player.  So, I have a second container div and a second adsManager with the exact dimensions as the video player for my non-overlay ads.

You can create two containers at the same time.  I have them both in the DOM on page load.

Vu Chau
IMA SDK Team

Screen Shot 2016-11-29 at 11.03.35 AM.png

Simon Ferndriger

unread,
Nov 30, 2016, 4:38:41 AM11/30/16
to Interactive Media Ads SDK
HI Vu Chau


Thank you very much!
However, there is one thing I don't really understand.

In setUpIMA() you create a new adsLoader with new google.ima.AdsLoader(adDisplayContainer);
But adDisplayContainer is undefined at this time, right? Could this parameter also be left out at this point?


Best
Simon

Simon Ferndriger

unread,
Nov 30, 2016, 4:47:17 AM11/30/16
to Interactive Media Ads SDK
I mean when you call setUpIMA() the first time in init(). Is this first setUpIMA() call necessary?

Simon Ferndriger

unread,
Nov 30, 2016, 8:57:12 AM11/30/16
to Interactive Media Ads SDK
Also, how can you ever show a postroll, if this event must be triggered by a user action:

// Initialize the container. Must be done via a user action on mobile devices.

Vu Chau (IMA SDK Team)

unread,
Nov 30, 2016, 10:12:45 AM11/30/16
to Interactive Media Ads SDK
Hi Simon,

You are correct.  On page load you can omit calling setUpIMA() until either of the two ad requests has been made.  

The user action is only required on the mobile web, so if your target audience is on desktop, you should be able to serve postrolls. Also, the initialization is only done in the beginning and not for every ad request, provided that you are using the same container for all your non-linear ads.  

There are two ways to render a postroll ad. You can leave it to the SDK by using a VMAP tag, so an ad request will automatically be sent out when you call contentComplete() to signify the content is over. Alternatively, you can send an ad request yourself at the very end of your content video (like you would do during your content playback), effectively imitating a postroll ad.

Vu Chau
IMA SDK Team

Simon Ferndriger

unread,
Dec 1, 2016, 9:14:49 AM12/1/16
to Interactive Media Ads SDK
Hi Vu Chau


Thanks - I got it rolling now, thanks to your help!
The current implementation is Desktop and Tablet only (does Tablet also count as "mobile"?) - but we also have a mobile version.

Would the "imitating" version work on mobiles?

PS: The text banners do have a nice shadow prerendered already, is it possible to opt-in a shadow for display banners also?


Best
Simon

Vu Chau (IMA SDK Team)

unread,
Dec 1, 2016, 11:13:18 AM12/1/16
to Interactive Media Ads SDK
Hi Simon,

Glad to know you found it helpful!

Tablet is also considered "mobile", but you can confirm this via comparing your user agent strings from Chrome desktop and Android Chrome. The user agents should be different.

I wouldn't have separate implementations for desktops and for mobiles, since your IMA implementation should work everywhere. What I'd do is to make sure 1) you are calling adDisplayContainer.initialize() and 2) you are calling it directly via a user tap. Implement it like that, and for desktop requests ad playback will work as we have seen, and for mobile web requests the second constraint will take effect.
PS: The text banners do have a nice shadow prerendered already, is it possible to opt-in a shadow for display banners also?
I'm not sure what you are referring to here. Feel free to send some screenshots if that helps.

Vu 

Simon Ferndriger

unread,
Dec 6, 2016, 5:03:01 AM12/6/16
to Interactive Media Ads SDK
Hi Vu


Yes, you really helped me here - big thanks again!
Now, there are just some smaller issue.

1) Shadow
Here is the shadow I was talking about, it makes the banner grounded (in a material design manner):



2) LinearAd Height

Also, what I wanted to ask you (again), is why you chose 150(px) as height for the overlay?

adsRequest.nonLinearAdSlotHeight = 150;

When positioning it manually, it is better to have the container fit to its content as much as possible. So every additional space makes it complicated.
I used "90" instead of "150" because that's the height of all banners that may appear here, correct?

Is there any special reason for chosing 150?


Best
Simon 

Simon Ferndriger

unread,
Dec 6, 2016, 5:14:53 AM12/6/16
to Interactive Media Ads SDK
However, when using only 90px as height, the overlay still appears as usual, however the postroll/fullslot does not anymore with the reason/error:
  1. Non linear assets were found in the VAST ad response, but none of them matched the video player's capabilities."

  2. I just don't understand why the height of the overlay should influence the fullslot (which has still the full player height)...

Vu Chau (IMA SDK Team)

unread,
Dec 6, 2016, 10:26:15 AM12/6/16
to Interactive Media Ads SDK
Hi Simon,

Shadow: I think this is out of scope for the IMA SDK. If the image comes with the shadow already then it will be displayed with it. You could confirm this theory by opening the standalone image - the link should be found in the VAST response. I'm not seeing any shadow with our sample nonlinear ad.

Linear/Nonlinear ad slot dimensions: These values are used to help the SDK pick the correct creative if multiple creatives are returned. If you have only one nonlinear ad, then you can provide approximate dimensions here. They do not need to match the ad's actual dimensions, but they are required parameters. If you do not want the ad to take up much more space than its actual size, you can resize the adsManager, like I did:
if (!ad.isLinear()) {
    videoContent.play();
    // If the ad is a nonlinear overlay, we want to the adsManager to have roughly the same size
    // so that it won't occupy other UI elements nearby outside the video player.
    adsManager.resize(ad.getWidth() + 10, ad.getHeight() + 10, google.ima.ViewMode.NORMAL);
}
I set my nonLinearAdSlotHeight to 90px and was able to see the fullslot ad. Are you sure that error wasn't caused by something else? 

Vu

Simon Ferndriger

unread,
Dec 13, 2016, 6:52:11 AM12/13/16
to Interactive Media Ads SDK
Thank you, Vu. I just left it at 150px for the moment.

But I ran into another interesting/unpleasant surprise:
When I define the nonLinearAdWidth to the available width when entering fullscreen (this is most likely), the banner does only show up, after entering fullscreen and calling resize() of course.
This is fine (even though it would be nice to have different banners available: one for nonfullscreen and one for sullcreen, is this possible?
But the problem is, that when I leave fullscreen (the banner disappears again) and enter fullscreen again, the banner does not show up anymore!

Is this intentional, that the banner only shows up the first time when switching from "havong-not-enough-space-for-the-banner-to-show" to "having-enough-space", but not the second?


Best
Simon

Simon Ferndriger

unread,
Dec 13, 2016, 10:07:06 AM12/13/16
to Interactive Media Ads SDK
Also, I figured out the height problem as well. When I use inspector, you can see that the div.ima-container has a 5px bottom margin which is empty for image ads, but filled with a "drop shadow" for text ads:


So, when using 95px of height, everything works just fine.

Vu Chau (IMA SDK Team)

unread,
Dec 13, 2016, 10:19:35 AM12/13/16
to Interactive Media Ads SDK
Hi Simon,

The SDK will select only one nonlinear banner to display. It won't go back and select a different one with a different size if your implementation changes its size. So in this case you might have to send a second request after you have gone full screen, with a new nonLinearAdSlotWidth value.

Let me know if you have additional questions,

Vu

Simon Ferndriger

unread,
Dec 14, 2016, 7:34:21 AM12/14/16
to Interactive Media Ads SDK
Hi Vu


Ah, OK - get it. Thank you.

Actually, I have such a question. Yesterday, overlay and postroll worked just fine. And now, today, without having changed anything, overlay still works, but instead of the postroll, I get this error:

"Non linear assets were found in the VAST ad response, but none of them matched the video player's capabilities."

Do you perhaps know what this means?


Thanks a lot!
Simon

Vu Chau (IMA SDK Team)

unread,
Dec 14, 2016, 10:04:14 AM12/14/16
to Interactive Media Ads SDK
Hey Simon,

That error means the VAST response for your postroll does not contain a compatible mediafile resource that is playable by the video player on the page.

To debug this, you can look into the network traffic and find out the extension (mp4, webm, etc.) of the mediafile that is downloaded. Then, check if the video player supports them. 

If you know your video player supports certain mediafile formats, you can prioritize them using adsRenderingSettings.mimeTypes. Alternatively, when you create your ad tags on DFP and/or AdSense, you can make sure you are serving a variety of mime types.

Vu Chau
IMA SDK Team  

Simon Ferndriger

unread,
Dec 14, 2016, 10:35:06 AM12/14/16
to Interactive Media Ads SDK
Hey Vu


OK, I understand.
1) I scanned the network for mp4 and webm - nothing there. Any other media extension I should look for?
2) We actually should only have pure display banners (no video) as ads, since we do not meet the requirements for video ads (yet)
3) We use a self-made player, does this change anything?
4) The same ad tag still works and shows post-roll with my old implementation without the overlay - does this help with finding out the issue here?

Thanks again in advance for your awesome help!

Best
Simon

Vu Chau (IMA SDK Team)

unread,
Dec 14, 2016, 11:15:50 AM12/14/16
to Interactive Media Ads SDK
Hi Simon,

Thanks for confirming that this is only happening to display ads. That explains why there was no mp4 or webm (or similar) when you went looking for them. Are we talking about the fullslot ad here?

If you are using the fullslot ad as your postroll ad, I don't see why it would give that error, unless the ad response really does not contain anything.

Since I'm sure your implementation has evolved since I gave you my test page, feel free to open a new forum thread with all the reproduction details, and I'll be happy to continue the investigation.

Vu

Simon Ferndriger

unread,
Dec 15, 2016, 4:00:11 AM12/15/16
to Interactive Media Ads SDK
Hi Vu

You are welcome.
Sure, it makes sense, I guess. Here is the new issue:


Simon
<fon
Reply all
Reply to author
Forward
0 new messages