Playing two different ads with IMA and Shaka Player

903 Views Asked by At

I have a simple setup where I have two buttons and a <video> element. I am using Shaka player to play an adaptive DASH file. I am also using Google's IMA Ads SDK to play ads along with the video.

The expected outcome is that when I press button 1, I should see the pre-roll 1 followed by video 1. When I press button 2, I should see the pre-roll 2 followed by video 2.

However, after clicking any button, the ad plays only once. If I toggle the buttons, the ads do not play thereafter. Am I missing anything here? Or do we need to somehow clear the ads request before making another request.

const adUrl1 = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonly&ciu_szs=300x250%2C728x90&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&correlator=";
const adUrl2 = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpost&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=";
const manifestUrl1 = "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd";
const manifestUrl2 = "https://storage.googleapis.com/shaka-demo-assets/angel-one/dash.mpd";

let player, ui, video, controls, adManager;

async function initApp() {
  shaka.polyfill.installAll();
  if (shaka.Player.isBrowserSupported()) {
    // When using the UI, the player is made automatically by the UI object.
    video = document.getElementById('video');
    ui = video['ui'];
    controls = ui.getControls();
    player = controls.getPlayer();

    // Listen for error events.
    player.addEventListener('error', onPlayerErrorEvent);
    // controls.addEventListener('error', onUIErrorEvent);
    adManager = player.getAdManager();

    // Attach player and ui to the window to make it easy to access in the JS console.
    window.player = player;
    window.ui = ui;
    window.video = video;
    window.controls = controls;
    window.adManager = adManager;
  } else {
    console.error("Browser not supported");
  }
}


function initializeAdManager() {
  const container = ui.getControls().getClientSideAdContainer();
  adManager.initClientSide(container, video);
}

function onError(error) {
  // Log the error.
  console.error('Error code', error.code, 'object', error);
}


async function playAd1() {
  console.log('playing Video with ads 1');
  initializeAdManager();
  fetchAd(adUrl1);
  await playVideo(manifestUrl1);
}

async function playAd2() {
  console.log('playing video with ads 2');
  initializeAdManager();
  fetchAd(adUrl2);
  await playVideo(manifestUrl2);
}

async function playVideo(url) {
  try {
    await player.load(url);
  } catch (e) {
    onError(e);
  }
}

function fetchAd(url) {
  const adRequest = new google.ima.AdsRequest();
  adRequest.adTagUrl = url;
  adManager.requestClientSideAds(adRequest);
}


function onPlayerErrorEvent(errorEvent) {
  // Extract the shaka.util.Error object from the event.
  onPlayerError(errorEvent.detail);
}

function onPlayerError(error) {
  // Handle player error
  console.error('Error code', error.code, 'object', error);
}

function onUIErrorEvent(errorEvent) {
  // Extract the shaka.util.Error object from the event.
  onPlayerError(errorEvent.detail);
}

document.addEventListener('shaka-ui-loaded', initApp);
<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-type"/>
    <title id="sample_app_page_title">Ad Ping</title>
    <!--for UI builds: -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.3.0/shaka-player.ui.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.3.0/controls.min.css" rel="stylesheet">
    <!-- IMA HTML5 SDK (for serving Client Side ads): -->
    <script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js" type="text/javascript"></script>
</head>
<body>
<button onclick="playAd1()">Play Video with Ad1</button>
<button onclick="playAd2()">Play Video with Ad2</button>
<div>


  <div data-shaka-player-cast-receiver-id="8D8C71A7" data-shaka-player-container>
    <video data-shaka-player controls autoplay id="video" style="width:400px; height:200px" />
  </div>
</div>

1

There are 1 best solutions below

0
On

Figured the answer. Please check the following snippet to see this in action.

// Copyright 2013 Google Inc. All Rights Reserved.
// You may study, modify, and use this example for any purpose.
// Note that this example is provided "as is", WITHOUT WARRANTY
// of any kind either expressed or implied.

var adsManager;
var adsLoader;
var adDisplayContainer = document.getElementById('adContainer');
var intervalTimer;
var videoContent = document.getElementById('contentElement');
var testButton1 = document.getElementById('playButton');
var testButton2 = document.getElementById('testButton');

const adUrl1 = "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%3Dskippablelinear&correlator=";
var adUrl2 = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpreonly&ciu_szs=300x250%2C728x90&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&correlator=";

const video1 = "https://storage.googleapis.com/gvabox/media/samples/stock.mp4";
const video2 = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"


function init() {
    
    testButton1.addEventListener('click', function(e){
        e.preventDefault();
        videoContent.setAttribute('src', video1);
    requestAds(adUrl1);
    });
    
    testButton2.addEventListener('click', function(e) {
    e.preventDefault();
    videoContent.setAttribute('src', video2);
    requestAds(adUrl2);
    });

}

function setUpIMA() {
    // Create the ad display container.
    createAdDisplayContainer();
    videoContent.load();
    adDisplayContainer.initialize();

    // Create ads loader.
    adsLoader = new google.ima.AdsLoader(adDisplayContainer);
    // 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,
                               onAdError,
                               false);
    
    
}

    
function createAdDisplayContainer() {
    // We assume the adContainer is the DOM id of the element that will house
    // the ads.
    adDisplayContainer = new google.ima.AdDisplayContainer(
                                                           document.getElementById('adContainer'), videoContent);
}



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

    adsRenderingSettings.restoreCustomPlaybackStateOnAdBreakComplete = true;

    ///adsRenderingSettings.AUTO_SCALE; 
    //console.log(typeof(auto));
    //console.log(AUTO_SCALE);
    // videoContent should be set to the content video element.
    adsManager = adsManagerLoadedEvent.getAdsManager(
                                                     videoContent, 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);

    try {
    // Initialize the ads manager. Ad rules playlist will start at this time.

    adsManager.init(adsRenderingSettings.AUTO_SCALE, adsRenderingSettings.AUTO_SCALE, google.ima.ViewMode.NORMAL);
        //console.log("size change");
    adsManager.resize(640,360, 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) {
    // An error may be thrown if there was a problem with the VAST response.
    videoContent.play();
  } 
}


function onAdEvent(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();
            }
            break;
        case google.ima.AdEvent.Type.STARTED:
                       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
                       //console.log(intervalTimer); 
                    //if(intervalTimer == )

            }
            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 requestAds(url){
    setUpIMA();
if (adsManager) {
    //console.log(adsManager);
    adsManager.destroy();
    //adsManager = null;
    //console.log(adsManager);
  }
  var adsRequest = new google.ima.AdsRequest();
  adsRequest.adTagUrl = url;

  // Specify the linear and nonlinear slot sizes. This helps the SDK to
  // select the correct creative if multiple are returned.
  adsRequest.linearAdSlotWidth = 640;
  adsRequest.linearAdSlotHeight = 400;
  adsRequest.nonLinearAdSlotWidth = 640;
  adsRequest.nonLinearAdSlotHeight = 150;

  //log("adsRequest: " + tag);
  adsLoader.requestAds(adsRequest);
}

function onAdError(adErrorEvent) {
    // Handle the error logging.
    console.log(adErrorEvent.getError());
    adsManager.destroy();
    alert('error in VAST response');
}

function onContentPauseRequested() {
    videoContent.pause();
    // This function is where you should setup UI for showing ads (e.g.
    // display ad timer countdown, disable seeking etc.)
    // setupUIForAds();
}

function onContentResumeRequested() {
    videoContent.play();
    // This function is where you should ensure that your UI is ready
    // to play content. It is the responsibility of the Publisher to
    // implement this function when necessary.
    // setupUIForContent();
    
}

// Wire UI element references and UI event listeners.
init();
#mainContainer {
  position: relative;
  width: 640px;
  height: 360px;
}

#content, #adContainer {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 640px;
  height: 360px;
}

#contentElement {
  width: 640px;
  height: 360px;
  overflow: hidden;
}

#playButton, #testButton{
  margin-top:10px;
  vertical-align: top;
  width: 350px;
  height: 60px;
  padding: 0;
  font-size: 22px;
  color: white;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  background: #2c3e50;
  border: 0;
  border-bottom: 2px solid #22303f;
  cursor: pointer;
  -webkit-box-shadow: inset 0 -2px #22303f;
  box-shadow: inset 0 -2px #22303f;
}
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
 <div id="mainContainer">
      <div id="content">
        <video id="contentElement">
          <!-- <source src="https://storage.googleapis.com/interactive-media-ads/media/android.mp4" /> -->
        </video>
      </div>
      <div id="adContainer"></div>
    </div>
    <button id="playButton">Btn1 </button>
    <button id="testButton">Btn 2</button>