Roller.js 7.81 KB
(function () {
    var adsManager;
    var adsLoader;
    var adDisplayContainer;
    var intervalTimer;
    var videoContent;
    var adTagUrl;
    var adContainerEl;
    var loadingMessageEl;

    window.roller = function (el, tagUrl) {
        videoContent = el;
        adTagUrl = tagUrl;

        // Play nicely with ad blockers.
        if (typeof google === 'undefined') {
            return;
        }

        setUpIMA();

        return {
            playAds: playAds,
            destroy: destroy,
        };
    };

    function setUpIMA() {
        // Create the ad display container.
        createAdDisplayContainer();
        // Create ads loader.
        adsLoader = new google.ima.AdsLoader(adDisplayContainer);

        // Enabled VPAID ads.
        adsLoader.getSettings().setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);

        // Listen and respond to ads loaded and error events.
        adsLoader.addEventListener(
            google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
            onAdsManagerLoaded,
            false);
        adsLoader.addEventListener(
            google.ima.AdErrorEvent.Type.AD_ERROR,
            onAdLoaderError,
            false);

        // Request video ads.
        var adsRequest = new google.ima.AdsRequest();
        adsRequest.adTagUrl = adTagUrl;

        // Specify the linear and nonlinear slot sizes. This helps the SDK to
        // select the correct creative if multiple are returned.
        adsRequest.linearAdSlotWidth = parseInt(getComputedStyle(videoContent.el).width, 10);
        adsRequest.linearAdSlotHeight = parseInt(getComputedStyle(videoContent.el).height, 10);

        adsRequest.nonLinearAdSlotWidth = getComputedStyle(videoContent.el).width;
        adsRequest.nonLinearAdSlotHeight = getComputedStyle(videoContent.el).height / 3;

        adsLoader.requestAds(adsRequest);
    }

    function createAdDisplayContainer() {
        adContainerEl = $('<div id="adContainer" style="background: #000; display:none; width: 100%; height: 100%; top: 0; left: 0; position: absolute;"></div>').insertAfter(videoContent.el)[0];

        loadingMessageEl = $('<div style="position: absolute; bottom: 10px; left: 15px; z-index: 99999;">Loading Advertisement ...</div>').appendTo(adContainerEl);

        adDisplayContainer = new google.ima.AdDisplayContainer(adContainerEl);
    }

    function playAds() {
        if (!adsManager) {
            return onContentResumeRequested();
        }

        // Initialize the container. Must be done via a user action on mobile devices.
        adDisplayContainer.initialize();

        // We want to show ad container now because it might take a while to
        // load the ad while user thinks the player just stopped.
        showAdsContainer();

        try {
            // Initialize the ads manager. Ad rules playlist will start at this time.
            adsManager.init(parseInt(getComputedStyle(videoContent.el).width, 10), parseInt(getComputedStyle(videoContent.el).height, 10), google.ima.ViewMode.NORMAL);
            // Call play to start showing the ad. Single video and overlay ads will
            // start at this time; the call will be ignored for ad rules.
            adsManager.start();
        } catch (adError) {
            onAdError(adError);
        }
    }

    function onAdsManagerLoaded(adsManagerLoadedEvent) {
        console.log('LOADED MANAGER');

        // Get the ads manager.
        var adsRenderingSettings = new google.ima.AdsRenderingSettings();

        adsRenderingSettings.loadVideoTimeout = 10000;

        // videoContent should be set to the content video element.
        adsManager = adsManagerLoadedEvent.getAdsManager({
            duration: 120,
            currentTime: 0,
        }, adsRenderingSettings
        );

        // Add listeners to the required events.
        adsManager.addEventListener(
            google.ima.AdErrorEvent.Type.AD_ERROR,
            onAdError);
        adsManager.addEventListener(
            google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED,
            onContentPauseRequested);
        adsManager.addEventListener(
            google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
            onContentResumeRequested);
        adsManager.addEventListener(
            google.ima.AdEvent.Type.ALL_ADS_COMPLETED,
            onAdEvent);

        // Listen to any additional events, if necessary.
        adsManager.addEventListener(
            google.ima.AdEvent.Type.LOADED,
            onAdEvent);
        adsManager.addEventListener(
            google.ima.AdEvent.Type.STARTED,
            onAdEvent);
        adsManager.addEventListener(
            google.ima.AdEvent.Type.COMPLETE,
            onAdEvent);
    }

    function onAdEvent(adEvent) {
        console.log(adEvent);

        // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)
        // don't have ad object associated.
        var ad = adEvent.getAd();
        switch (adEvent.type) {
            case google.ima.AdEvent.Type.LOADED:
                // This is the first event sent for an ad - it is possible to
                // determine whether the ad is a video ad or an overlay.
                if (!ad.isLinear()) {
                    // Position AdDisplayContainer correctly for overlay.
                    // Use ad.width and ad.height.
                    videoContent.play();
                    hideAdsContainer();
                }
                break;
            case google.ima.AdEvent.Type.STARTED:
                loadingMessageEl.remove();

                // This event indicates the ad has started - the video player
                // can adjust the UI, for example display a pause button and
                // remaining time.
                if (ad.isLinear()) {
                    // For a linear ad, a timer can be started to poll for
                    // the remaining time.
                    intervalTimer = setInterval(
                        function () {
                            var remainingTime = adsManager.getRemainingTime();
                        },
                        300); // every 300ms
                }
                break;
            case google.ima.AdEvent.Type.COMPLETE:
                // This event indicates the ad has finished - the video player
                // can perform appropriate UI actions, such as removing the timer for
                // remaining time detection.
                if (ad.isLinear()) {
                    clearInterval(intervalTimer);
                }
                break;
        }
    }

    function onAdLoaderError(adErrorEvent) {
        console.log(adErrorEvent.getError());
    }

    function onAdError(adErrorEvent) {
        /**
         * We use this handler for all errors and sometimes they are not
         * google.ima.AdErrorEvent type and they don't have .getError() method.
         */
        console.log((adErrorEvent.getError && adErrorEvent.getError()) || adErrorEvent);

        onContentResumeRequested();

        if (adsManager) {
            adsManager.destroy();
        }
    }

    function onContentPauseRequested() {
        showAdsContainer();

        videoContent.pause();
    }

    function onContentResumeRequested() {
        hideAdsContainer();

        videoContent.play();
    }

    function showAdsContainer() {
        console.log('SHOW');

        adContainerEl.style.display = 'block';
    }

    function hideAdsContainer() {
        console.log('HIDE');

        adContainerEl.style.display = 'none';
    }

    function destroy() {
        if (adDisplayContainer) {
            adDisplayContainer.destroy();
        }

        if (adsLoader) {
            adsLoader.destroy();
        }

        if (adsManager) {
            adsManager.destroy();
            adsManager = undefined;
        }

        if (adContainerEl.parentNode) {
            adContainerEl.parentNode.removeChild(adContainerEl);
        }
    }
}());