Get Started

Note: Dynamic ad insertion requires that you have an Ad Manager 360 account and an account manager. Please contact your account manager if you are interested in signing up.

This guide details the steps necessary to play dynamic-ad-insertion (DAI) streams with the IMA SDK using hls.js. It discusses both live streams and video on demand (VOD) streams. To follow along with a finished sample, download our BasicExample.

Create the HTML

Create a file called dai.html containing the following:

  <script src="//"></script>
  <script type="text/javascript" src="//"></script>
  <script src="dai.js"></script>
  <link rel="stylesheet" href="dai.css" type="text/css">
<body onLoad="initPlayer()">
  <h2>IMA SDK DAI Demo (HLS.JS)</h2>
    <video id="video"></video>
    <div id="click"></div>
  1. Add library references for hls.js and the IMA DAI SDK, respectively, using <script> tags.
  2. In the body of the document, set up a <video> tag with a click <div> below it, used for clickthrough.
  3. Call initPlayer() in the onLoad function to initialize your video player. (This is explained in more detail below.)

Create the CSS

Create a file called dai.css containing the following:

#video, #click {
  width: 640px;
  height: 360px;
  position: absolute;
  top: 35px;
  left: 0px;

#click {
  cursor: pointer;

#banner {
  width: 100%;
  height: 35px;
  background-color: black;
  color: white;
  position: absolute;
  top: 0px;
  left: 0px;

This establishes the styling information for the page, which is especially important for the click handler.

Create the JavaScript

Now create a new file called dai.js. This is used by your HTML page to perform all player logic on your page.

Initialize the StreamManager

In dai.js, set up some variables to hold the information required to request a stream from the DAI server.

    '' +

// Live stream asset key.

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

var streamManager;   // used to request ad-enabled streams.
var hls = new Hls(); // hls.js video player
var videoElement;
var clickElement;

Then, initialize StreamManager and request a VOD stream.

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

  // 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 our metadata, we 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.pts);

  // 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);

This function initializes a StreamManager which is responsible for requesting and managing DAI streams. The constructor takes a video element and the resulting StreamManager is passed a click element: the <div> you provide to the SDK to handle ad clicks.

Next, you need to implement event listeners for major video events. Our simple example handles the LOADED, ERROR, AD_BREAK_STARTED and AD_BREAK_ENDED events by calling onStreamEvent(). We construct the onStreamEvent() handler function below.

Finally, to support live streams, add a handler to listen to timed metadata events and forward these events to the StreamManager.

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

Request the stream

Add a requestVODStream() function to handle VOD streams, and a similar function for live streams:

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

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

These functions create new StreamRequest objects, either VOD or live. The objects are interchangeable, so depending on your use case, have your page call one of these two methods. Both methods take an optional API key. If you're using an encrypted stream, you need to create a DAI authentication key.

Handle stream events

Earlier you hooked up all of your event handlers to the onStreamEvent() function. We now show how to implement that function:

function onStreamEvent(e) {
  switch (e.type) {
    case google.ima.dai.api.StreamEvent.Type.LOADED:
      console.log('Stream loaded');
    case google.ima.dai.api.StreamEvent.Type.ERROR:
      console.log('Error loading stream, playing backup stream.' + e);
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_STARTED:
      console.log('Ad Break Started');
      videoElement.controls = false; = 'block';
    case google.ima.dai.api.StreamEvent.Type.AD_BREAK_ENDED:
      console.log('Ad Break Ended');
      videoElement.controls = true; = 'none';

Our function handles stream loading and errors, as well as disabling the player controls while an ad is playing--this is required by the SDK. When the stream is loaded, the video player is instructed to load and play the provided URL in the loadUrl() function:

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

Congratulations, you now have a working IMA DAI implementation for HTML5.

Send feedback about...

Need help? Visit our support page.