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 client-side SDKs, you maintain control of content video playback, while the SDK handles ad playback. Ads play in a separate video player positioned on top of the app's content video player.
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. If you're interested in an HTML5 player with the SDK pre-integrated, check out the IMA SDK Plugin for Video.js.
IMA client-side overview
Implementing IMA client-side involves four main SDK components, which are demonstrated in this guide:
AdDisplayContainer
: A container object where ads are rendered.AdsLoader
: An object that requests ads and handles events from ads request responses. You should only instantiate one ads loader, which can be reused throughout the life of the application.AdsRequest
: An object that defines an ads request. Ads requests specify the URL for the VAST ad tag, as well as additional parameters, such as ad dimensions.AdsManager
: An object that contains the response to the ads request, controls ad playback, and listens for ad events fired by the SDK.
Prerequisites
Before you begin, you'll need the following:
- Three empty files:
- index.html
- style.css
- ads.js
- Python installed on your computer, or a web server to use for testing
1. Start a development server
Since the IMA SDK loads dependencies via 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.
- Using a command line, from the directory that contains
your index.html file run:
python -m http.server 8000
- In a web browser, go to
http://localhost:8000/
You can also use any other web server, such as the Apache HTTP Server.
2. Create a simple video player
First, modify index.html to create a simple HTML5 video element, contained in a wrapping element, and a button to trigger playback. Also add the necessary tags to load the style.css and ads.js files. Then, modify styles.css to make the video player responsive for mobile devices. Finally, in ads.js, trigger video playback when the play button is clicked.
index.html<!doctype html> <html lang="en"> <head> <title>IMA HTML5 Simple Demo</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="style.css"> </head> <body> <div id="page-content"> <div id="video-container"> <video id="video-element"> <source src="https://storage.googleapis.com/interactive-media-ads/media/android.mp4"> <source src="https://storage.googleapis.com/interactive-media-ads/media/android.webm"> </video> </div> <button id="play-button">Play</button> </div> <script src="ads.js"></script> </body> </html>
#page-content { position: relative; /* this element's width controls the effective height */ /* of the video container's padding-bottom */ max-width: 640px; margin: 10px auto; } #video-container { position: relative; /* forces the container to match a 16x9 aspect ratio */ /* replace with 75% for a 4:3 aspect ratio, if needed */ padding-bottom: 56.25%; } #video-element { /* forces the contents to fill the container */ position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
var videoElement; // On window load, attach an event to the play button click // that triggers playback on the video element window.addEventListener('load', function(event) { videoElement = document.getElementById('video-element'); var playButton = document.getElementById('play-button'); playButton.addEventListener('click', function(event) { videoElement.play(); }); });
After completing this step, when you open index.html in your browser (via your development server) you should be able to see the video element and the video should start when you click the play button.
3. Import the IMA SDK
Next, add the IMA framework using a script tag in index.html, before the tag for
ads.js
.
... </video> </div> <button id="play-button">Play</button> </div> <script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script> <script src="ads.js"></script> </body> </html>
4. Attach page and video player handlers
To modify the behavior of the video player with JavaScript, add event handlers that trigger the following actions:
- When the page is finished loading, initialize the IMA SDK.
- When the video play button is clicked, load ads (unless there are already ads loaded).
- When the browser window is resized, update the video element and
adsManager
dimensions to make the page responsive for mobile devices
var videoElement; // Define a variable to track whether there are ads loaded and initially set it to false var adsLoaded = false; window.addEventListener('load', function(event) { videoElement = document.getElementById('video-element'); initializeIMA(); videoElement.addEventListener('play', function(event) { loadAds(event); }); var playButton = document.getElementById('play-button'); playButton.addEventListener('click', function(event) { videoElement.play(); }); }); window.addEventListener('resize', function(event) { console.log("window resized"); }); function initializeIMA() { console.log("initializing IMA"); } function loadAds(event) { // Prevent this function from running on if there are already ads loaded if(adsLoaded) { return; } adsLoaded = true; // Prevent triggering immediate playback when ads are loading event.preventDefault(); console.log("loading ads"); }
5. Create the ad container
In most browsers, the IMA SDK uses a dedicated ad container element for displaying both ads and
ad-related UI elements. This container must be sized to overlay the video element from the
top-left corner. The height and width of the ads placed in this container are set by the
adsManager
object, so you don't need to set these values manually.
To implement this ad container element, first create a new div
within the
video-container
element. Then, update the CSS to position the element at the top-left
corner of the video-element
. Finally, define a variable for the container within the
initializeIMA()
function that runs when the page is loaded.
... <div id="video-container"> <video id="video-element" controls> <source src="https://storage.googleapis.com/interactive-media-ads/media/android.mp4"> <source src="https://storage.googleapis.com/interactive-media-ads/media/android.webm"> </video> <div id="ad-container"></div> </div> ...
... #ad-container { position: absolute; top: 0; left: 0; width: 100%; }
var videoElement; var adsLoaded = false; var adContainer; ... function initializeIMA() { console.log("initializing IMA"); adContainer = document.getElementById('ad-container'); }
6. Initialize the AdsLoader and make an ads request
In order to request a set of ads, create an ima.AdsLoader
instance. This instance
takes an AdDisplayContainer
object as an input and can be used to process
ima.AdsRequest
objects associated with a specified ad tag URL. The ad tag used in
this example contains a 10-second pre-roll ad. You can test this, or any, ad tag URL using the
IMA Video Suite Inspector.
As a best practice, only maintain one instance of ima.AdsLoader
for the entire
lifecycle of a page. To make additional ad requests, create a new ima.AdsRequest
object, but re-use the same ima.AdsLoader
. For more information, see the
IMA SDK FAQ.
var videoElement; var adsLoaded = false; var adContainer; var adDisplayContainer; var adsLoader; ... function initializeIMA() { console.log("initializing IMA"); adContainer = document.getElementById('ad-container'); adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, videoElement); adsLoader = new google.ima.AdsLoader(adDisplayContainer); // Let the AdsLoader know when the video has ended videoElement.addEventListener('ended', function() { adsLoader.contentComplete(); }); var adsRequest = new google.ima.AdsRequest(); adsRequest.adTagUrl = 'https://pubads.g.doubleclick.net/gampad/ads?' + 'iu=/21775744923/external/single_ad_samples&sz=640x480&' + 'cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&' + 'gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator='; // Specify the linear and nonlinear slot sizes. This helps the SDK to // select the correct creative if multiple are returned. adsRequest.linearAdSlotWidth = videoElement.clientWidth; adsRequest.linearAdSlotHeight = videoElement.clientHeight; adsRequest.nonLinearAdSlotWidth = videoElement.clientWidth; adsRequest.nonLinearAdSlotHeight = videoElement.clientHeight / 3; // Pass the request to the adsLoader to request ads adsLoader.requestAds(adsRequest); }
7. Listen for AdsLoader events
When ads are loaded successfully, the ima.AdsLoader
emits an
ADS_MANAGER_LOADED
event. Parse the event passed to the callback to initialize the
AdsManager
object. The AdsManager
loads the individual ads as defined by the response to the ad
tag URL.
In addition, be sure to handle any errors that may occur during the loading process. If ads do not load, make sure that media playback continues, without ads, so as to not interfere with the user's experience.
ads.jsvar videoElement; var adsLoaded = false; var adContainer; var adDisplayContainer; var adsLoader; var adsManager; ... function initializeIMA() { console.log("initializing IMA"); adContainer = document.getElementById('ad-container'); adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, videoElement); adsLoader = new google.ima.AdsLoader(adDisplayContainer); adsLoader.addEventListener( google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded, false); adsLoader.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError, false); ... function onAdsManagerLoaded(adsManagerLoadedEvent) { // Instantiate the AdsManager from the adsLoader response and pass it the video element adsManager = adsManagerLoadedEvent.getAdsManager( videoElement); } function onAdError(adErrorEvent) { // Handle the error logging. console.log(adErrorEvent.getError()); if(adsManager) { adsManager.destroy(); } }
8. Start the AdsManager
To start ad playback, you need to start the AdsManager
. To fully support mobile
browsers, this should be triggered by a user interaction.
... function loadAds(event) { // prevent this function from running on every play event if(adsLoaded) { return; } adsLoaded = true; // prevent triggering immediate playback when ads are loading event.preventDefault(); console.log("loading ads"); // Initialize the container. Must be done via a user action on mobile devices. videoElement.load(); adDisplayContainer.initialize(); var width = videoElement.clientWidth; var height = videoElement.clientHeight; try { adsManager.init(width, height, google.ima.ViewMode.NORMAL); adsManager.start(); } catch (adError) { // Play the video without ads, if an error occurs console.log("AdsManager could not be started"); videoElement.play(); } } ...
9. Make the AdsManager responsive
To make sure that ads dynamically resize to match the size of the video player, if the screen
changes size or orientation, the window resize event must call adsManager.resize()
.
... window.addEventListener('resize', function(event) { console.log("window resized"); if(adsManager) { var width = videoElement.clientWidth; var height = videoElement.clientHeight; adsManager.resize(width, height, google.ima.ViewMode.NORMAL); } }); ...
10. Listen for AdsManager events
The AdsManager
also fires several events that must be handled. These events are used
to track state changes, trigger play and pause on the content video, and register errors.
Handling errors
The error handler created for the AdsLoader
can serve as the error handler for the
AdsManager
by adding a new event handler with the same callback function.
... function onAdsManagerLoaded(adsManagerLoadedEvent) { adsManager = adsManagerLoadedEvent.getAdsManager( videoElement); adsManager.addEventListener( google.ima.AdErrorEvent.Type.AD_ERROR, onAdError); } ...
Triggering play and pause events
When the AdsManager
is ready to insert an ad for display, it fires the
CONTENT_PAUSE_REQUESTED
event. Handle this event by triggering a pause on the
underlying video player. Similarly, when an ad completes, the AdsManager
fires the
CONTENT_RESUME_REQUESTED
event. Handle this event by restarting playback on the
underlying content video.
... function onAdsManagerLoaded(adsManagerLoadedEvent) { adsManager = adsManagerLoadedEvent.getAdsManager( videoElement); 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); } ... function onContentPauseRequested() { videoElement.pause(); } function onContentResumeRequested() { videoElement.play(); }
Triggering click-to-pause on mobile devices
Since the AdContainer
overlays the video element, users cannot interact directly with
the underlying player. This can confuse users on mobile devices, who expect to be able to tap a
video player to pause playback. To address this issue, the IMA SDK passes any clicks that are not
handled by IMA from the ad overlay to the AdContainer
element, where they can be
handled. This does not apply to linear ads on non-mobile browsers, as clicking the ad opens the
clickthrough link.
To implement click-to-pause, add a click handler to the AdContainer
and trigger play
or pause events on the underlying video.
... function initializeIMA() { console.log("initializing IMA"); adContainer = document.getElementById('ad-container'); adContainer.addEventListener('click', adContainerClick); adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, videoElement); adsLoader = new google.ima.AdsLoader(adDisplayContainer); ... function adContainerClick(event) { console.log("ad container clicked"); if(videoElement.paused) { videoElement.play(); } else { videoElement.pause(); } } ...
Triggering play on non-linear ads
The AdsManager
pauses the content video when an ad is ready to play, but this
behavior doesn't account for non-linear ads, where the content should continue to play while the
ad is displayed. To support non-linear ads, listen for the AdsManager
to emit the
LOADED
event. Then, check if the ad is linear, and if not, resume playback on the
video element.
... function onAdsManagerLoaded(adsManagerLoadedEvent) { adsManager = adsManagerLoadedEvent.getAdsManager( videoElement); 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.LOADED, onAdLoaded); } ... function onAdLoaded(adEvent) { var ad = adEvent.getAd(); if (!ad.isLinear()) { videoElement.play(); } }
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.