Skipping ads in HTML5 using autoPlayAdBreaks(false, adsManager.stop(), and adsManager.start()

893 views
Skip to first unread message

Lee Whitaker

unread,
Jun 16, 2015, 8:54:32 PM6/16/15
to ima...@googlegroups.com
We have a requirement from a publisher to skip prerolls which take "too long" to load.  To implement it with the HTML5 SDK we are attempting to use the autoPlayAdBreaks(false) feature along with the adsManager.start() and adsManager.stop() methods.

In Flash, we were able to implement this by doing something like this (I've removed the code we have around checking if its a preroll for simplicity):

adsManager.init(stage.stageWidth, stage.stageHeight, ViewModes.NORMAL);

private function adLoadedHandler(event:AdEvent):void {
  // A linear ad had loaded. It's time to remove spinner animation.
  if (!_autoPlayAdBreaks && _adtimeout) {
    adsManager.stop();
  }
}

private function contentPauseRequestedHandler(event:AdEvent):void {
  //we haven't timed out always start it
  if (!_adtimeout) {
    playerCall('ads.startLinearAdMode');
    adPlayerTrigger('play');
  }
}

private function adBreakReadyHandler(event:AdEvent):void {
  //If we've timed out, don't start the adManager and ignore the ad all-together.
  if(adtimeout) {
    console('adBreakReadyHandler: skipping preroll ad due to timeout, not starting ads manager');
    return;
  }
  adsManager.start();
}

This seems to work just fine in flash and we can restart the adManager for subsequent midroll and postroll adBreaks when the adBreakReady event fires.  However, in HTML5, we've got similar code setup:

try {
  player.ima3.adsManager.init(player.width(), player.height(), ima.ViewMode.NORMAL);
} catch (adError) {
  player.trigger('adserror');
}

adBreakReadyHandler = function(event) {
  // if this is not a pre-roll or the timeout has not expired, play it immediately.
  if (adtimeout) {
    console.log('Skipping preroll ad because the timeout has elapsed and autoPlayAdBreaks was set false.');
    console.log('Set autoPlayAdBreaks true if you want prerolls to always play.');
  } else {
    try {
      player.ima3.adsManager.start();
    } catch (adError) {
      player.trigger('adserror');
    }
  }
};

contentPauseRequestedHandler function(event) {
  //If we are not autoplaying ad breaks and the ad has timed out, 
  //stop the adManager to skip it.
  if (!player.ima3.adsLoader.getSettings().isAutoPlayAdBreak() && adstimeout) {
    player.ima3.adsManager.stop();
  } else {
    player.ads.startLinearAdMode();
  }
});

But after stopping the adsManager if a preroll times out, the adBreakReady events stop firing so we never have an opprtunity to restart it and all subsequent midrolls and postrolls are skipped too.  I tried to mimic flash exactly and stop the adsManager in the adsLoadedHandler but we were seeing that the contentPauseRequested handler was getting triggered anyway so moving it there in HTML5 made the most sense.  Is it expected that the adBreakReady handler's would not fire after we stop the adsManager in HTML5?

Lee Whitaker

unread,
Jun 17, 2015, 12:22:41 PM6/17/15
to ima...@googlegroups.com
I realize my pseudo code is difficult to rely on.  Here is an example I've published which shows the bug:

The example above has these diffs from your published example:

This diff, which also uses manual adbreaks but doesn't ever stop the adsManager demonstrates that adBreaks will continue to fire as long as you don't stop the adsManager:

Tyler Sidell (IMA SDK Team)

unread,
Jun 17, 2015, 3:51:08 PM6/17/15
to ima...@googlegroups.com
Hi Lee,

Calling the adsManager.stop() method should not have an effect on adBreakReadyHandler from firing.  The event listener does not get removed.

Have you followed the steps under "Disabling Automatic Playback of Ad Breaks" and set:
adsLoader.getSettings().setAutoPlayAdBreaks(false);

I would suggest instead of adsManager.stop trying adsManager.pause instead.  The main difference being that you can .resume() if you .pause() on the AdsManager.

Another suggestion to handle timeouts would be to load the adsLoader and adsManager in the background, even before the user initializes playback.  When the user taps to start the video, the prerolls should be ready to playback smoothly without timing out.

Thanks,
Tyler Sidell
IMA SDK Team

Lee Whitaker

unread,
Jun 17, 2015, 4:40:54 PM6/17/15
to ima...@googlegroups.com
Hi Tyler.  Thank you for the response.

Have you seen the example I posted in my update?

In that example, I believe I have implemented the ad breaks as documented in the article you linked.

I am setting the adsLoader.getSettings().setAutoPlayAdBreaks(false); here in that example.

We are trying to implement a timeout in our case, so based on the reference docs description of the pause() method I didn't think it would work as it would no-op:

Pauses the current ad that is playing. This function will be no-op when a static overlay is being shown or if the ad is not loaded yet or is done playing.

stop() seemed to have the behavior we were looking for:

Stop playing the ads. Calling this will get publisher back to the content.

Unfortunately, as noted, this seems to halt the AD_BREAK_READY events and also doesn't call the contentResume handler as we would have expected based on the behavior of the same feature in the flash SDK.

I have implemented it with adsManager.pause() as you suggested trying and that doesn't do the trick either.  I see that this pauses the preroll while content plays behind it and then eventually contentResume is called removing the preroll.  However, even if I can figure how to get back to content mode, this also stopped subsequent AD_BREAK_READY events from firing.

I am using the example VMAP - Pre-roll Single Ad, Mid-roll Standard Pod with 3 ads, Post-roll Single Ad from here so there should be an adBreak with multiple midrolls and a postroll after the prerolls.
 
Lee

Tyler Sidell (IMA SDK Team)

unread,
Jun 18, 2015, 1:59:28 PM6/18/15
to ima...@googlegroups.com
Hi Lee,

Thank you for providing your example.  

From the console log, after onContentPauseRequested is called (where it stops the adsManager), the ad break is destroyed:
onContentPauseRequested_
[  3.056s] [ima.adslist.AdBreak] Destroying the ad break, 0

This situation is tricky because if you stop the adsManager, you won't be able to resume the manager.  So since you are calling adsManager.stop() for preroll (assuming there is a timeout), the adsManager no longer functions and thus doesn't fire adBreakReady. 

A workaround for skipping the prerolls if it there is a timeout without stopping the adsManager would be to:

1) Disable auto-playback of ad breaks (which is already present in your example)
2) AD_BREAK_READY handler: check the podIndex of the current ad. If it's not 0, play the ad. (Prerolls have a podIndex of 0)

Give this a try and let me know if you have any questions,

Tyler Sidell
IMA SDK Team

Lee Whitaker

unread,
Jun 18, 2015, 4:36:02 PM6/18/15
to ima...@googlegroups.com
Unfortunately simply not starting the adsManager isn't a solution for us since that is necessary for the adrequest to be made.  In our use case, we want to make the adrequest in all cases but exit actually rendering it and continue on with the content if its taking too long to retrieve the ad content.

In our testing, adBreaks in the Flash SDK continue to fire when stop() is called so we were hoping this to be the case in the HTML5 SDK too.  It seems a bit heavy handed that stopping the adManager and thus destroying an adBreak has the side effect of destroying the adsManager all-together?  What you describe makes it seem that calling stop() is pretty much the same as calling destroy().

Is there any chance the HTML5 SDK will be made to behave more similarly to flash in this case and continue to fire adBreaks?  If not, can you offer a workaround or alternative approach to ignoring an ad after the adsManager has already kicked off the request?

Tyler Sidell (IMA SDK Team)

unread,
Jun 19, 2015, 2:24:22 PM6/19/15
to ima...@googlegroups.com
Hi Lee,

Although adsManager.stop() and adsManager.destroy() might sound similar, 
adsManager.destroy() removes all ad assets at the time of ad completion.
adsManager.stop() stops playing the ads but does not remove the assets.

Have you tried the workaround that I recommended?

Another workaround that I would suggest is to remove adsManager.start() from the Ad Break Ready listener.  Normally you would call adsManager.start() in this event listener, but in this scenario the SDK would hold that ad break in queue.  Then if another ad break comes along later, the newer ad break would get played instead of the previous one.  Thus effectively skipping the previous ad break.

Thanks,
Tyler Sidell 
IMA SDK Team

Lee Whitaker

unread,
Jun 19, 2015, 3:02:41 PM6/19/15
to ima...@googlegroups.com
Hi Tyler,  

The use case we've been asked to implement is not to skip ads entirely but to skip them conditionally when the ad asset is taking too long to start.  In other words, to have a timeout on the preroll request that when expired would cause the entire preroll adBreak to be skipped but still play any subsequent ad breaks (midrolls/postrolls).

Because calling adManager.start() is required in order to trigger the preroll ad creative request, the workaround you proposed won't work for this use case.  Any other ideas?

Lee

Tyler Sidell (IMA SDK Team)

unread,
Jun 19, 2015, 4:39:47 PM6/19/15
to ima...@googlegroups.com
Hi Lee,

Have you given adsRenderingSettings.loadVideoTimeout a try?  I'm not sure if this will fit your specific requirements but you'll be able to set the timeout and if the ad takes longer to load than this threshold, the ad playback is cancelled and the next ad in the pod is played.

Thanks,
Tyler Sidell
IMA SDK Team

Lee Whitaker

unread,
Jun 22, 2015, 10:04:04 AM6/22/15
to ima...@googlegroups.com
Hi Tyler.  Thanks for the suggestion again. Unfortunately, as you hinted at, this won't fit our specific requirements either.  We need to stop/exit from the entire adBreak/pod on a timeout and not just a specific ad in that break.  

With the flag you suggested, if you consider an adBreak/pod that has three ads, there is the possibility that you need to wait for all three of these ads to timeout.  Our use case, considers one timeout enough reason to exit the break/pod.

If the adManager continued to fire the AD_BREAK_READY events after .stop() is invoked and would startup again on .start() I think we could accomplish this use case.

Lee

Tyler Sidell (IMA SDK Team)

unread,
Jun 22, 2015, 2:48:33 PM6/22/15
to ima...@googlegroups.com
Hi Lee,

I've been included on the separate thread.  Can we continue the conversation there to avoid duplication?

Thanks,
Tyler Sidell
IMA SDK Team

Lee Whitaker

unread,
Jun 22, 2015, 3:47:40 PM6/22/15
to ima...@googlegroups.com
Yes, please. Thank you.
Reply all
Reply to author
Forward
0 new messages