The VAST response document is empty & Unable to request ads from server due to network error issue

602 views
Skip to first unread message

Nour-Eddine Alouane

unread,
Nov 8, 2016, 5:57:45 AM11/8/16
to Interactive Media Ads SDK
Hi

We are trying to make vast tags work properly with in our app, but the results are not stable, most of the time tags are not rendered.

1-We are using ima sdk for HTML5 (ima3)
3-With Video Suite Inspector, the tag is working properly,
  1-You can see the issue in this link: http://d27gxpwhxqw4fq.cloudfront.net/#/ChoufTV/1478274043
This is actually is a video player. The strange thing is that when we are using this cloudfront domaine, we get this error: "Unable to request ads from server due to network error issue" at 100%, but when using this link: http://52.208.147.119/embed/#/ChoufTV/1478274043 we get this error: "The VAST response document is empty", and with a local link during development: http://localhost:9000/#/Chouftv/1478274043 we get always the same ad (it's fullscreen with no skip button, even if the vast tag contains a skip button)
We are really stuck with this issue, if anyone can help us with a hint or a clarification about this issue

Vu Chau (IMA SDK Team)

unread,
Nov 8, 2016, 11:21:18 AM11/8/16
to Interactive Media Ads SDK
Hi Nour-Eddine,

This is very likely a player + implementation issue, since you and I confirmed the tag itself works fine in the Video Suite Inspector.

Would you be able to show us the un-minified JS that you use to load IMA and render ads? Here's my suggestions on how to troubleshoot the errors:
    • Unable to request ads from server due to network error issue
      • Make sure there is no protocol disagreement between your ad tag, the webpage, and any third-party URLs that contain the actual ad mediafile to be rendered.  What I mean by that is that HTTPS should be present across your implementation.  For example, if your page protocol is HTTPS, the tag protocol is HTTP, and your mediafile is requested via HTTP, this network error will be thrown.
    • The VAST response document is empty
      • This is more of a serving error than SDK or network.  If either the tag has frequency capping in place, or the server thinks the page is requesting the same tag multiple times, an empty VAST response will be sent back to the requesting client.  Make sure that if you request against the same tag consecutively that you call contentComplete() on the adsLoader and destroy the adsManager before making your next ad request.
    • We get always the same ad (it's fullscreen with no skip button, even if the vast tag contains a skip button)
      • You might want to diversify the ads returned on AdSense's side of things.  If I can see the actual ad response and a page, I could look into this more.
    Vu Chau
    IMA SDK Team

    Nour-Eddine Alouane

    unread,
    Nov 8, 2016, 1:54:37 PM11/8/16
    to Interactive Media Ads SDK
    Hi Vu Chau,

    Yes of course I can show you the js code. But before that, here is some extra detail about the app:

    the audience for this app is huge, so we decided to use cdn for hosting 99% of the app, so we don't have to pay for the bandwidth out from the 
    server

    So with this cdn domain we have the following infos:
    1-page protocol can be http or https, but we are using only http for the moment
    2-mediafile could be requested by http or https, we are using currently http
    3-ima sdk is requested with https
    4-google analytics lib is requested using https
    5-all assets (css, js, img) can be requested by https, but we are using currently http
    6- one single server request is using http, we didn't purchase an https certificat yet for this server
    7-ad requested using https

    So can you suggest us an edit to this config to fix the first issue, for example de we need to use https or http for everything?


    About the second issue (The VAST response document is empty), currently we are using a new tag only for development (requesting the same tag multiple times), but previously we deployed the 
    player for two big sites, and 32% of the ads were rejected with this error (600 ads per second fail), we reported this issue to our tag provider 
    (he is working with ad exchange) but still on hold. I think what you mentioned about contentComplete is probably the issue, I will late you take a look to the js code and hopefully we find the issue

    For the third issue, I think it's juste temporary because it's the first time that happens

    Thanks in advance, I really appreciate your time and your help Vu Chau
    Thanks again

    Here is the js code it's written with angularjs:

    "use strict";
    angular.module("com.2fdevs.videogular.plugins.imaads", [])
        .directive(
        "vgImaAds",
        ["$window", "VG_STATES", function ($window, VG_STATES) {
            return {
                restrict: "E",
                require: "^videogular",
                scope: {
                    vgNetwork: "=?",
                    vgUnitPath: "=?",
                    vgCompanion: "=?",
                    vgCompanionSize: "=?",
                    vgAdTagUrl: "=?",
                    vgPreroll: "=?",
                    vgMidroll: "=?",
                    vgPostroll: "=?",
                    vgSkipButton: "=?"
                },
                link: function (scope, elem, attr, API) {

                    var adsManager = null;
                    var adsLoaded = false;
                    var w;
                    var h;
                    var startplay = false;
                    var onContentEnded = function () {
                        adsLoader.contentComplete();
                    };
                    var currentAd = 0;
                    var currentIsLinear = true;
                    var skipButton = angular.element(scope.vgSkipButton);
                    var videoFinished = false;
                    var adContainerDiv = elem[0];

                    //Lang ads
                    google.ima.settings.setLocale('ar');

                    var adDisplayContainer = new google.ima.AdDisplayContainer(adContainerDiv);
                    var adsLoader = new google.ima.AdsLoader(adDisplayContainer);
                    adsLoader.getSettings().setVpaidMode( google.ima.ImaSdkSettings.VpaidMode.ENABLED);
                    scope.onAdsManagerLoaded = function onAdsManagerLoaded(adsManagerLoadedEvent) {
                        console.log('onAdsManagerLoaded');
                        scope.show();
                        adsManager = adsManagerLoadedEvent.getAdsManager(API.mediaElement[0]);
                        scope.processAdsManager(adsManager);
                    };
                    scope.onAdError = function onAdError(err) {
                        console.log('Ad Error');
                        console.log(err);
                        ga('send', 'event', 'video', 'AD Error: '+err.b.h.toString(), "ChoufTV");
                         // $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('width', '0%');
                         $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('height', '100px');

                        if (!videoFinished) API.play();
                        if (currentAd==1) {
                            console.log(adsManager);
                            if (adsManager){
                                adsManager.destroy();
                              //  adsLoader.contentComplete();
                            }
                            if(scope.vgMidroll.active){
                                console.log('midroll');
                                ga('send', 'event', 'video', 'Midroll AD Request', "ChoufTV");
                                API.play();
                                scope.requestAds(scope.vgMidroll.url);
                                currentAd++;
                            }
                        }
                        if(currentAd==2){
                            if (adsManager){
                                adsManager.destroy();
                             //   adsLoader.contentComplete()
                            }
                            scope.hide();
                        }
                    };
                    adsLoader.addEventListener(
                      google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
                      scope.onAdsManagerLoaded,
                      false);
                    adsLoader.addEventListener(
                      google.ima.AdErrorEvent.Type.AD_ERROR,
                      scope.onAdError,
                      false);
                    
                    scope.API = API;

                    scope.LunchPostroll = function(){
                        ga('send', 'event', 'video', 'Video Finished', "ChoufTV");
                        videoFinished =  true;
                        if(adsManager){
                            adsLoader.contentComplete();
                            adsManager.destroy();
                        }
                        
                        if(scope.vgPostroll.active){
                            console.log('postroll');
                            ga('send', 'event', 'video', 'Postroll AD Request', "ChoufTV");
                            scope.requestAds(scope.vgPostroll.url);
                        }
                        
                    }

                    API.onComplete = scope.LunchPostroll;

                    scope.onUpdateState = function onUpdateState(newState) {
                        switch (newState) {
                            case VG_STATES.PLAY:
                                if (currentAd==0 && (scope.vgPreroll.active || scope.vgMidroll.active)) {
                                    API.pause();
                                    currentAd++;
                                    if(scope.vgPreroll.active) {
                                        console.log('Preroll ad');
                                        console.log('vgPreroll.active');
                                        ga('send', 'event', 'video', 'Preroll AD Request', "ChoufTV");
                                        scope.requestAds(scope.vgPreroll.url);
                                    }
                                    else if(scope.vgMidroll.active) {
                                        console.log('vgMidroll.active');
                                        ga('send', 'event', 'video', 'Midroll AD Request', "ChoufTV");
                                        scope.requestAds(scope.vgMidroll.url);  
                                    }
                                }
                                break;

                            case VG_STATES.STOP:
                                // adsManager.destroy();
                                adsLoader.contentComplete();
                                break;
                        }
                    };

                    scope.requestAds = function requestAds(adTagUrl) {
                        // Show only to get computed style in pixels
                        scope.show();
                        console.log('requestAds');
                        scope.resetIMA_();

                        adDisplayContainer.initialize();
                        var adsRequest = new google.ima.AdsRequest();
                        var computedStyle = $window.getComputedStyle(elem[0]);

                        adsRequest.adTagUrl = adTagUrl;
                        adsRequest.linearAdSlotWidth = parseInt(computedStyle.width, 10);
                        adsRequest.linearAdSlotHeight = parseInt(computedStyle.height, 10);
                        adsRequest.nonLinearAdSlotWidth = parseInt(computedStyle.width, 10);
                        adsRequest.nonLinearAdSlotHeight = parseInt(computedStyle.height, 10);
                        adsRequest.forceNonLinearFullSlot = true;
                        adsRequest.supportsYouTubeHosted = true;
                        console.log(adsRequest);
                       // console.log(adsLoader);
                        adsLoader.requestAds(adsRequest);
                    };

                    
                    scope.processAdsManager = function processAdsManager(adsManager) {
                        w = API.videogularElement[0].offsetWidth;
                        h = API.videogularElement[0].offsetHeight;

                        // Attach the pause/resume events.
                        adsManager.addEventListener(google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED, scope.onContentPauseRequested, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, scope.onContentResumeRequested, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.SKIPPABLE_STATE_CHANGED, scope.onSkippableStateChanged, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.ALL_ADS_COMPLETED, scope.onAllAdsComplete, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.COMPLETE, scope.onAdComplete, false, this);
                        adsManager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, scope.onAdError, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.LOADED, scope.onAdLOADED, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.AD_BREAK_READY, scope.onAd_BREAK_READY, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.SKIPPED, scope.onAdSKIPPED, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED, scope.onAdCONTENT_RESUME_REQUESTED, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.CLICK, scope.onAdCLICK, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.STARTED, scope.onAdSTARTED, false, this);
                        adsManager.addEventListener(google.ima.AdEvent.Type.USER_CLOSE, scope.onAdUSER_CLOSE, false, this);
                       
                       try {
                        adsManager.init(w, h, google.ima.ViewMode.NORMAL);
                        }
                        catch(adError){
                            console.log('----------AdError----------');
                            ga('send', 'event', 'video', 'AD Error', "ChoufTV");
                            console.log(adError);
                        }
                        adsManager.start();
                    };

                    scope.onAd_BREAK_READY = function(){
                        console.log('onAd_BREAK_READY');
                    }
                    scope.onAdSKIPPED = function(){
                        console.log('onAdSKIPPED');
                        ga('send', 'event', 'video', 'AD Skipped', "ChoufTV");
                    }
                    scope.onAdCLICK = function(){
                        console.log('onAdCLICK');
                        ga('send', 'event', 'video', 'AD Clicked', "ChoufTV");
                    }
                    scope.onAdSTARTED = function(){
                        console.log('onAdSTARTED');
                        ga('send', 'event', 'video', 'AD Started', "ChoufTV");
                    }
                    scope.onAdUSER_CLOSE = function(){
                        console.log('USER_CLOSE');
                        ga('send', 'event', 'video', 'AD User Close', "ChoufTV");
                    }
                    scope.onAdCONTENT_RESUME_REQUESTED = function(){
                        console.log('onAdCONTENT_RESUME_REQUESTED');
                       // $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('width', '100%');
                      //  $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('height', '100%');
                            $('vg-ima-ads').css("bottom", "46px");
                        if (currentAd==1) {
                            if(adsManager){

                                adsManager.destroy();
                                adsLoader.contentComplete();
                            }
                            if(scope.vgMidroll.active){
                                console.log('midroll');
                                ga('send', 'event', 'video', 'Midroll AD Request', "ChoufTV");
                                API.play();
                                scope.requestAds(scope.vgMidroll.url);
                                currentAd++;
                            }
                        }
                    }

                    scope.onAdLOADED = function(){
                        console.log('onAdLOADED');
                        currentIsLinear = adsManager.getCurrentAd().b.linear; 
                        console.log(adsManager.getCurrentAd().b.width);
                        console.log(adsManager.getCurrentAd().b.height);
                        if(currentIsLinear){
                            console.log('linear');
                            ga('send', 'event', 'video', 'Linear AD Loaded', "ChoufTV");
                            $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('width', '100%');
                            $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('height', '100%');
                            $('vg-ima-ads iframe').css("position", "absolute");
                            $('vg-ima-ads iframe').css("top", "0px");
                            $('vg-ima-ads').css("bottom", "0px");
                        }
                        else{
                            console.log('non linear');
                            ga('send', 'event', 'video', 'NonLinear AD Loaded', "ChoufTV");
                            $('vg-ima-ads').css("bottom", "46px");
                            setTimeout(function() {
                                var ad_width = adsManager.getCurrentAd().b.width + 10;
                                if(ad_width==10) ad_width = 450;
                                var ad_height = adsManager.getCurrentAd().b.height + 10;
                                $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('height', ad_height+'px');
                                $('vg-ima-ads, vg-ima-ads div, vg-ima-ads iframe').css('width', ad_width+'px');
                                
                            }, 200);

                            if (!videoFinished) API.play();
                        }
                    }

                    scope.onSkippableStateChanged = function onSkippableStateChanged() {
                        var isSkippable = adsManager.getAdSkippableState();

                        if (isSkippable) {
                            skipButton.css("display", "block");
                        }
                        else {
                            skipButton.css("display", "none");
                        }
                    };

                    scope.onClickSkip = function onClickSkip() {
                        adsManager.skip();
                    };

                    scope.onContentPauseRequested = function onContentPauseRequested() {
                        scope.show();
                        API.mediaElement[0].removeEventListener('ended', onContentEnded);
                        API.pause();
                    };

                    scope.onContentResumeRequested = function onContentResumeRequested() {
                        API.mediaElement[0].addEventListener('ended', onContentEnded);

                        if (!videoFinished) API.play();
                        scope.hide();
                    };

                    scope.onAllAdsComplete = function onAllAdsComplete() {
                        scope.hide();
                        console.log('onAllAdsComplete');
                        // The last ad was a post-roll
                        if (adsManager.getCuePoints().join().indexOf("-1") >= 0) {
                            API.stop();
                        }
                    };

                    scope.onAdComplete = function onAdComplete() {
                        // TODO: Update view with current ad count
                         console.log('onAdComplete');
                    };

                    scope.resetIMA_ = function() {
                      if (adsManager) {
                        adsManager.destroy();
                        adsManager = null;
                      }
                      if (adsLoader) {
                        adsLoader.contentComplete();
                      }
                    };

                    scope.show = function show() {
                        elem.css("display", "block");
                    };

                    scope.hide = function hide() {
                        elem.css("display", "none");
                    };

                    skipButton.bind("click", scope.onClickSkip);

                    elem.prepend(skipButton);

                    angular.element($window).bind("resize", function () {
                        w = API.videogularElement[0].offsetWidth;
                        h = API.videogularElement[0].offsetHeight;

                        if (adsManager) {
                            if (API.isFullScreen) {
                                adsManager.resize(w, h, google.ima.ViewMode.FULLSCREEN);
                            }
                            else {
                                adsManager.resize(w, h, google.ima.ViewMode.NORMAL);
                            }
                        }
                    });

                    if (API.isConfig) {
                        scope.$watch("API.config",
                            function () {
                                if (scope.API.config) {
                                    scope.vgNetwork = scope.API.config.plugins["ima-ads"].network;
                                    scope.vgUnitPath = scope.API.config.plugins["ima-ads"].unitPath;
                                    scope.vgCompanion = scope.API.config.plugins["ima-ads"].companion;
                                    scope.vgCompanionSize = scope.API.config.plugins["ima-ads"].companionSize;
                                    scope.vgAdTagUrl = scope.API.config.plugins["ima-ads"].adTagUrl;
                                    scope.vgSkipButton = scope.API.config.plugins["ima-ads"].skipButton;
                                }
                            }
                        );
                    }
                
                    scope.$watch(
                        function () {
                            return API.currentState;
                        },
                        function (newVal, oldVal) {
                            if (newVal != oldVal) {
                                scope.onUpdateState(newVal);
                            }
                        }
                    );
                }
            }
        }]
    );


    Vu Chau (IMA SDK Team)

    unread,
    Nov 8, 2016, 3:42:45 PM11/8/16
    to Interactive Media Ads SDK
    Hello,
    So can you suggest us an edit to this config to fix the first issue, for example de we need to use https or http for everything?
    I put together a table that shows all possible combinations of protocols, and how each would affect your implementation.  Take a look at the attached "HTTP/HTTPS expectations" table. 

    Your code looks fine to me. For each ad request, you are making the call to resetIMA_ to destroy the adsManager and call contentComplete() on the adsLoader, which is expected of your use case. This might ultimately be due to the server having low inventory, and not serving an ad as a result. If so, your team should check your serving settings with AdX.  I'm repeatedly requesting against your ad tag and I can see it serves each time.

    Let me know if you have any questions,

    Vu Chau
    IMA SDK Team

    HTTP:HTTPS expectations.png
    Reply all
    Reply to author
    Forward
    0 new messages