Audio ads

The IMA HTML5 SDK supports audio ads with a similar setup as video ads but with a few key differences. For any part of the IMA setup not covered in this guide, see the HTML5 Get started guide.

Use of an <audio> tag for content playback

The constructor for AdDisplayContainer takes a second argument named videoElement which IMA tracks as the content player. This argument accepts both a <video> or <audio> tag. For audio content and ads, this guide recommends using an <audio> tag to construct an AdDisplayContainer. If you have video content, you can use a <video> tag for showing a mix of audio and video ads:

index.html

<audio id="audio-player"></audio>
<div class="ad-container"></div>

ads.js

audioPlayer = document.getElementById('audio-player');
adContainer = document.getElementById('ad-container');
adDisplayContainer = new google.ima.AdDisplayContainer(adContainer,
audioPlayer);

Hiding the AdDisplayContainer

The IMA HTML5 SDK still requires an AdDisplayContainer even if there is no display portion to the ads or content. For this reason, we recommend hiding the AdDisplayContainer. Below is an example of how you can hide the element:

style.css

.ad-container {
  display: none;
}

Custom controls

Because the AdDisplayContainer is hidden, custom controls are needed to handle playback during ad breaks. AdsManager has methods that can be used to implement these custom controls:

Handling skippable ads

Because there is no visible AdDisplayContainer, the IMA SDK cannot show a Skip ad button. To handle skippable ads, implement the following IMA methods:

The sample code below demonstrates how to do this.

ads.js

You can set up an updateSkippable function to determine whether and when an ad can be skipped. This function should be called on each AD_PROGRESS IMA event. See the Getting started guide for directions on how to set up listeners for IMA events.

function onAdsManagerLoaded(adsManagerLoadedEvent) {
  adsManager = adsManagerLoadedEvent.getAdsManager(
    audioPlayer);

  ...

  adsManager.addEventListener(
    google.ima.AdEvent.Type.AD_PROGRESS,
    onAdEvent(event));

  ...

}

function onAdEvent(adEvent) {
  const ad = adEvent.getAd();
  if (ad) {
    currentAd = ad; // currentAd is defined outside of this functions scope.
  }
  switch (adEvent.type) {

    ...

    case google.ima.AdEvent.Type.AD_PROGRESS:
      // See https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdProgressData
      const adProgressData = adEvent.getAdData();

      updateSkippable(
        adProgressData.currentTime,
        currentAd.getSkipTimeOffset()
      );
      break;
    ...

  }
}

/**
   * Called when there may be a change in the skippable state.
   * @param {number} currentTime The current time of the
   * currently playing ad.
   * @param {number} skipTimeOffset The number of seconds of playback
   * before the ad becomes skippable. -1 is returned for non skippable
   * ads or if this is unavailable.
   */
  updateSkippable(currentTime, skipTimeOffset) {
    const isAdSkippable = skipTimeOffset !== -1;
    const isSkipCurrentlyAllowed = adsManager.getAdSkippableState();
    const timeTillSkipInSeconds = Math.ceil(skipTimeOffset - currentTime);
    updateSkipUI(
        isAdSkippable, isSkipCurrentlyAllowed, timeTillSkipInSeconds);
  }

Unlike with video ads, IMA is not able to provide a skip button for audio ads. Developers must add custom UI for skippable ads, which can be done with a simple <button> tag. This updateSkipUI function updates the skip button based on if the ad is skippable, if the ad is currently skippable, and how much time is remaining until the ad becomes skippable. It makes use of the '.hidden' class, which is not provided by IMA. The .hidden class adds display: none; to the <button>.

/**
 * Updates the skip button UI.
 * @param {boolean} isAdSkippable if the current ad is a skippable ad.
 * @param {boolean} isSkipCurrentlyAllowed if the ad can be skipped now.
 * @param {number} timeTillSkipInSeconds time until the ad can be skipped in
 * seconds.
 */
updateSkipUI(isAdSkippable, isSkipCurrentlyAllowed, timeTillSkipInSeconds) {
  if (isAdSkippable) {
    skipButton.classList.remove('hidden');
    if (isSkipCurrentlyAllowed) {
      skipButton.textContent = 'Skip ad';
      skipButton.disabled = false;
    } else {
      skipButton.textContent = `Skip in ${timeTillSkipInSeconds} seconds`;
      skipButton.disabled = true;
    }
  } else {
    skipButton.classList.add('hidden');
  }
}

Finally, set a listener for user clicks on your custom skip button. To skip ads, call the adsManager.skip() function.

skipButton.addEventListener('click', () => {
  adsManager.skip();
});

These are the main changes needed to set up the IMA SDK with audio ads. For answers to implementation issues, visit the IMA SDK Technical Forum.