Get started with the IMA DAI SDK

IMA SDKs make it easy to integrate multimedia ads into your websites and apps. IMA SDKs can request ads from any VAST-compliant ad server and manage ad playback in your apps. With IMA DAI SDKs, apps make a stream request for ad and content video—either VOD or live content. The SDK then returns a combined video stream, so that you don't have to manage switching between ad and content video within your app.

Select the DAI solution you're interested in

Full service DAI

This guide demonstrates how to integrate the IMA SDK into a simple video player app. If you would like to view or follow along with a completed sample integration, download the simple example from GitHub.

IMA DAI overview

Implementing IMA DAI involves two main SDK components as demonstrated in this guide:

  • StreamRequest— either a VODStreamRequest or a LiveStreamRequest: An object that defines a stream request. Stream requests can either be for video-on-demand or live streams. Requests specify a content ID, as well as an API key or authentication token and other parameters.
  • StreamManager: An object that handles dynamic ad insertion streams and interactions with the DAI backend. The stream manager also handles tracking pings and forwards stream and ad events to the publisher.

Prerequisites

  • Three empty files
    • dai.html
    • dai.css
    • dai.js
  • Python installed on your computer, or a web server to use for testing

Start a development server

Since the IMA SDK loads dependencies using the same protocol as the page from which it's loaded, you need to use a web server to test your app. The simplest way to start a local development server is to use Python's built-in server.

  1. Using a command line, from the directory that contains your index.html file run:

    python -m http.server 8000
    
  2. In a web browser, go to to http://localhost:8000/

    You can also use any other web server, such as the Apache HTTP Server.

Create a simple video player

First, modify dai.html to create a simple HTML5 video element and a div to use for the clickthrough. Also add the necessary tags to load the dai.css and dai.js files, as well as to import the hls.js video player. Then, modify dai.css to specify the size and position of the page elements. Finally, in dai.js, define variables to hold the stream request information and an initPlayer() function to run when the page loads.

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>
<body onLoad="initPlayer()">
  <h2>IMA SDK DAI Demo (HLS.JS)</h2>
    <video id="video"></video>
    <div id="ad-ui"></div>
</body>
</html>

dai.css

#video,
#ad-ui {
  width: 640px;
  height: 360px;
  position: absolute;
  top: 35px;
  left: 0;
}

#ad-ui {
  cursor: pointer;
}

dai.js

var BACKUP_STREAM =
    'https://storage.googleapis.com/interactive-media-ads/media/bbb.m3u8'

// Livestream asset key.
var TEST_ASSET_KEY = "sN_IYUG8STe1ZzhIIE_ksA";

// VOD content source and video IDs.
var TEST_CONTENT_SOURCE_ID = "2548831";
var TEST_VIDEO_ID = "tears-of-steel";

var hls = new Hls(); // hls.js video player
var videoElement;
var adUiElement;
var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
}

Load the IMA SDK

Next, add the IMA framework using a script tag in dai.html, before the tag for dai.js.

dai.html

<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
  <script type="text/javascript" src="//imasdk.googleapis.com/js/sdkloader/ima3_dai.js"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
</head>

Initialize the StreamManager and make a stream request

In order to request a set of ads, create an ima.dai.api.StreamManager, which is responsible for requesting and managing DAI streams. The constructor takes a video element and the resulting instance takes an ad UI element to handle ad clicks.

Then, define functions that request streams. This example includes functions for both VOD and livestreams, which create instances of VODStreamRequest and LiveStreamRequest, respectively, and then call streamManager.requestStream() with the streamRequest parameters. For livestreams, you also need to add a handler to listen to timed metadata events and forward the events to the StreamManager. You can comment or uncomment the code to fit your use case. Both methods take an optional API key. If you're using a protected stream, you need to create a DAI authentication key.

Neither stream in this example is protected, so apiKey is not used.

dai.js

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement)

  // Timed metadata is only used for LIVE streams.
  hls.on(Hls.Events.FRAG_PARSING_METADATA, function(event, data) {
    if (streamManager && data) {
      // For each ID3 tag in the metadata, pass in the type - ID3, the
      // tag data (a byte array), and the presentation timestamp (PTS).
      data.samples.forEach(function(sample) {
        streamManager.processMetadata('ID3', sample.data, sample.pts);
      });
    }
  });

  requestVODStream(TEST_CONTENT_SOURCE_ID, TEST_VIDEO_ID, null);
  // Uncomment the line below and comment out the one above to request a
  // LIVE stream instead of a VOD stream.
  //requestLiveStream(TEST_ASSET_KEY, null);
}

function requestVODStream(cmsId, videoId, apiKey) {
  var streamRequest = new google.ima.dai.api.VODStreamRequest();
  streamRequest.contentSourceId = cmsId;
  streamRequest.videoId = videoId;
  streamRequest.apiKey = apiKey;
  streamManager.requestStream(streamRequest);
}

function requestLiveStream(assetKey, apiKey) {
  var streamRequest = new google.ima.dai.api.LiveStreamRequest();
  streamRequest.assetKey = assetKey;
  streamRequest.apiKey = apiKey;
  streamManager.requestStream(streamRequest);
}

Handle stream events

Finally, you need to implement event listeners for major video events. This simple example handles the LOADED, ERROR, AD_BREAK_STARTED and AD_BREAK_ENDED events by calling an onStreamEvent() function. This function handles stream loading and errors, as well as disabling the player controls while an ad is playing, which is required by the SDK. When the stream is loaded, the video player loads and plays the provided URL using a loadUrl() function.

You might also want to set up event listeners for the video element's pause and start events to allow the user to resume playback when the IMA pauses during ad breaks.

To work with DAI, your custom player must pass ID3 events for livestreams to the IMA SDKs as shown in the sample code.

dai.js

var isAdBreak;

function initPlayer() {
  videoElement = document.getElementById('video');
  adUiElement = document.getElementById('adUi');
  streamManager = new google.ima.dai.api.StreamManager(videoElement, adUiElement);
  videoElement.addEventListener('pause', onStreamPause);
  videoElement.addEventListener('play', onStreamPlay);

  streamManager.addEventListener(
    [google.ima.dai.api.StreamEvent.Type.LOADED,
     google.ima.dai.api.StreamEvent.Type.ERROR,
     google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED,
     google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED],
    onStreamEvent,
    false);
...
function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.LOADED:
      console.log('Stream loaded');
      loadUrl(e.getStreamData().url);
      break;
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
      loadUrl(BACKUP_STREAM);
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      isAdBreak = true;
      videoElement.controls = false;
      adUiElement.style.display = 'block';
      break;
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      isAdBreak = false;
      videoElement.controls = true;
      adUiElement.style.display = 'none';
      break;
    default:
      break;
  }
}

function loadUrl(url) {
  console.log('Loading:' + url);
  hls.loadSource(url);
  hls.attachMedia(videoElement);
  hls.on(Hls.Events.MANIFEST_PARSED, function() {
    console.log('Video Play');
    videoElement.play();
  });
}

function onStreamPause() {
  console.log('paused');
  if (isAdBreak) {
    videoElement.controls = true;
    adUiElement.style.display = 'none';
  }
}

function onStreamPlay() {
  console.log('played');
  if (isAdBreak) {
    videoElement.controls = false;
    adUiElement.style.display = 'block';
  }
}

That's it! You're now requesting and displaying ads with the IMA SDK. To learn about more advanced SDK features, see the other guides or the samples on GitHub.