IMA SDK for Video Players: Complete Integration Guide for Web, Android, and iOS
The Google IMA SDK provides a client-side solution for loading and playing video ads across six lifecycle stages: SDK import, initialization, ad request, load handling, playback events, and cleanup.
The IMA SDK for video players enables developers to monetize content with interactive media ads across multiple platforms. According to the google/skills repository, the SDK supports web browsers, Android devices, iOS/tvOS systems, and connected TVs through a unified architecture adapted to each native environment.
IMA SDK Lifecycle Overview
The SDK follows a consistent six-stage workflow regardless of platform. Understanding these stages ensures reliable ad delivery and prevents memory leaks.
Stage 1: Import the SDK
Load the JavaScript library from the Google CDN to make the google.ima namespace available.
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
Mobile platforms use package managers: Gradle for Android (com.google.ads.interactivemedia:interactivemedia:3.31.0), CocoaPods/SPM for iOS.
Stage 2: Initialization
Configure global settings via google.ima.settings before creating containers. This sets locale, VPAID mode, and other preferences that apply to all ad requests.
Key objects created:
- AdDisplayContainer: Binds an HTML element for ads to your content video
- AdsLoader: Handles the ad-request lifecycle
Stage 3: Ad Request
Construct an AdsRequest, set the ad tag URL, and declare playback capabilities:
const request = new google.ima.AdsRequest();
request.adTagUrl = 'https://example.com/adtag.xml';
request.setAdWillAutoPlay(true);
request.setAdWillPlayMuted(false);
adsLoader.requestAds(request);
Stage 4: Ad Load Success or Failure
Listen for AdsManagerLoadedEvent (success) and AdErrorEvent (failure). On success, retrieve the AdsManager, initialize with player dimensions, and start playback.
Stage 5: Ad Playback Events
The AdsManager emits critical events including CONTENT_PAUSE_REQUESTED and CONTENT_RESUME_REQUESTED. Hook these to synchronize your content player with ad playback.
Stage 6: Cleanup
Always destroy resources to prevent memory leaks:
adsManager?.destroy();
adsLoader.contentComplete();
adDisplayContainer.destroy();
Web Integration (HTML5 TypeScript)
The web implementation relies on SKILL.md and ima-sdk-web-guide.md in the google/skills repository for best practices.
HTML Structure
<div id="playerContainer" style="position:relative;width:640px;height:360px;">
<video id="contentVideo" style="width:100%;height:100%;"></video>
<div id="adContainer"
style="position:absolute;top:0;left:0;width:100%;height:100%;z-index:10;"></div>
</div>
Complete TypeScript Implementation
let adsLoader: google.ima.AdsLoader;
let adDisplayContainer: google.ima.AdDisplayContainer;
let adsManager: google.ima.AdsManager | null = null;
// Configure global settings early
google.ima.settings.setLocale('en');
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);
// Create UI containers
const adDiv = document.getElementById('adContainer') as HTMLElement;
const video = document.getElementById('contentVideo') as HTMLVideoElement;
adDisplayContainer = new google.ima.AdDisplayContainer(adDiv, video);
adsLoader = new google.ima.AdsLoader(adDisplayContainer);
// Hook loader events
adsLoader.addEventListener(
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
onAdsManagerLoaded
);
adsLoader.addEventListener(
google.ima.AdErrorEvent.Type.AD_ERROR,
onAdError
);
function requestAd(adTagUrl: string, autoPlay: boolean, muted: boolean) {
adDisplayContainer.initialize(); // Must follow user gesture
const request = new google.ima.AdsRequest();
request.adTagUrl = adTagUrl;
request.setAdWillAutoPlay(autoPlay);
request.setAdWillPlayMuted(muted);
adsLoader.requestAds(request);
}
function onAdsManagerLoaded(e: google.ima.AdsManagerLoadedEvent) {
const renderingSettings = new google.ima.AdsRenderingSettings();
adsManager = e.getAdsManager(video, renderingSettings);
adsManager.addEventListener(
google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED,
() => video.pause()
);
adsManager.addEventListener(
google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED,
() => video.play()
);
adsManager.addEventListener(
google.ima.AdErrorEvent.Type.AD_ERROR,
onAdError
);
try {
adsManager.init(640, 360, google.ima.ViewMode.NORMAL);
adsManager.start();
} catch (err) {
onAdError(err);
}
}
function onAdError(event: any) {
console.error('IMA error:', event);
cleanupAds();
video.play();
}
function cleanupAds() {
adsManager?.destroy();
adsManager = null;
adsLoader.contentComplete();
adDisplayContainer.destroy();
}
Android Integration (Kotlin)
Android implementations use the ima-sdk-android-guide.md reference. The Kotlin API mirrors the web lifecycle with native Android patterns.
// Gradle dependency
implementation("com.google.ads.interactivemedia:interactivemedia:3.31.0")
// Activity implementation
private lateinit var adDisplayContainer: AdDisplayContainer
private lateinit var adsLoader: AdsLoader
private var adsManager: AdsManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
IMASdkFactory.getInstance().settings.locale = "en"
IMASdkFactory.getInstance().settings.vpaidMode = IMASettings.VpaidMode.ENABLED
val adContainer = findViewById<FrameLayout>(R.id.adContainer)
val videoView = findViewById<VideoView>(R.id.contentVideo)
adDisplayContainer = AdDisplayContainer(adContainer, videoView)
adsLoader = AdsLoader(this, adDisplayContainer)
adsLoader.addAdsLoadedListener { manager -> onAdsManagerLoaded(manager) }
adsLoader.addAdErrorListener { error -> onAdError(error) }
}
private fun requestAd(adTagUrl: String) {
val request = AdsRequest().apply {
this.adTagUrl = adTagUrl
setAdWillAutoPlay(true)
setAdWillPlayMuted(false)
}
adsLoader.requestAds(request)
}
private fun onAdsManagerLoaded(manager: AdsManager) {
adsManager = manager
manager.addAdEventListener { event ->
when (event.type) {
AdEvent.Type.CONTENT_PAUSE_REQUESTED -> videoView.pause()
AdEvent.Type.CONTENT_RESUME_REQUESTED -> videoView.start()
}
}
manager.addAdErrorListener { error -> onAdError(error) }
manager.init(640, 360, ViewMode.NORMAL)
manager.start()
}
private fun onAdError(error: AdError) {
Log.e("IMA", "Error: ${error.message}")
adsManager?.destroy()
adsLoader.contentComplete()
videoView.start()
}
iOS Integration (Swift)
iOS developers reference ima-sdk-ios-guide.md and ima-sdk-tvos-guide.md for platform-specific guidance. The Swift implementation uses delegate patterns familiar to iOS developers.
import GoogleInteractiveMediaAds
class PlayerViewController: UIViewController {
private var adDisplayContainer: IMAAdDisplayContainer!
private var adsLoader: IMAAdsLoader!
private var adsManager: IMAAdsManager?
override func viewDidLoad() {
super.viewDidLoad()
IMASettings.shared().locale = "en"
IMASettings.shared().vpaidMode = .enabled
let adContainer = UIView(frame: view.bounds)
view.addSubview(adContainer)
let contentPlayer = AVPlayerViewController()
addChild(contentPlayer)
view.addSubview(contentPlayer.view)
adDisplayContainer = IMAAdDisplayContainer(
adContainer: adContainer,
companionSlots: nil
)
adsLoader = IMAAdsLoader(settings: IMASettings.shared())
adsLoader.delegate = self
}
func requestAd(tagUrl: String) {
let request = IMAAdsRequest(
adTagUrl: tagUrl,
adDisplayContainer: adDisplayContainer,
contentPlayhead: nil,
userContext: nil
)
request.adWillAutoPlay = true
request.adWillPlayMuted = false
adsLoader.requestAds(with: request)
}
}
extension PlayerViewController: IMAAdsLoaderDelegate {
func adsLoader(_ loader: IMAAdsLoader, didReceive adsLoadedData: IMAAdsLoadedData) {
adsManager = adsLoadedData.adsManager
adsManager?.delegate = self
adsManager?.initialize(with: IMAAdsRenderingSettings())
adsManager?.start()
}
func adsLoader(_ loader: IMAAdsLoader, didFailWithErrorData errorData: IMAAdLoadingErrorData) {
print("IMA load error: \(errorData.adError.message)")
}
}
extension PlayerViewController: IMAAdsManagerDelegate {
func adsManager(_ manager: IMAAdsManager, didReceive event: IMAAdEvent) {
switch event.type {
case .contentPauseRequested:
// Pause content player
break
case .contentResumeRequested:
// Resume content player
break
default:
break
}
}
func adsManager(_ manager: IMAAdsManager, didReceive error: IMAAdError) {
print("IMA playback error: \(error.message)")
manager.destroy()
}
}
Platform-Specific Reference Files
The google/skills repository organizes IMA SDK documentation by platform:
| Platform | Reference File | Purpose |
|---|---|---|
| Web | ima-sdk-web-guide.md |
HTML5/JS integration, lifecycle events |
| Android | ima-sdk-android-guide.md |
Kotlin/Java implementation patterns |
| iOS | ima-sdk-ios-guide.md |
Swift/Objective-C integration |
| tvOS | ima-sdk-tvos-guide.md |
Apple TV-specific considerations |
| Special | ima-sdk-web-iframe-mode.md |
AMP and iframe environments |
| Special | ima-sdk-web-mobile-safari.md |
Autoplay and muted policy handling |
Critical Implementation Details
User Gesture Requirements
Call adDisplayContainer.initialize() only after a user interaction. This satisfies browser autoplay policies and mobile Safari restrictions documented in ima-sdk-web-mobile-safari.md.
Error Handling Strategy
Distinguish between non-fatal LOG events (diagnostics only) and fatal AD_ERROR events (require cleanup and content fallback). Always implement both AdErrorEvent listeners on AdsLoader and AdsManager.
Memory Management
Nullify references after destroy() calls:
adsManager.destroy();
adsManager = null; // Prevent stale reference usage
Summary
- Import early: Load the SDK and configure
google.ima.settingsbefore creating containers - Initialize after gesture:
AdDisplayContainer.initialize()requires user interaction on web - Request with context: Set
adWillAutoPlayandadWillPlayMutedaccurately for optimal ad selection - Listen comprehensively: Handle both
AdsManagerLoadedEventandAdErrorEventon the loader - Synchronize playback: Respond to
CONTENT_PAUSE_REQUESTEDandCONTENT_RESUME_REQUESTEDto coordinate ad and content playback - Destroy completely: Call
destroy()on all three main objects (AdsManager,AdsLoader.contentComplete(),AdDisplayContainer) to prevent memory leaks
Frequently Asked Questions
What is the minimum IMA SDK version for modern mobile browsers?
The google/skills repository does not specify minimum versions in the analyzed files. However, the Android example uses version 3.31.0 as a current stable reference point. Check the official IMA SDK release notes for deprecation schedules and feature availability.
Why does my ad fail to load on mobile Safari?
Mobile Safari enforces strict autoplay and muted policies. The ima-sdk-web-mobile-safari.md file documents that you must call adDisplayContainer.initialize() within a user gesture handler, and accurately declare setAdWillPlayMuted(true) when appropriate. Incorrect capability reporting causes silent failures.
How do I implement IMA SDK in a React or Angular application?
The web integration patterns in ima-sdk-web-guide.md apply directly to framework implementations. Create the AdDisplayContainer and AdsLoader in a component's initialization lifecycle, store references in instance variables or refs, and call destroy() in cleanup handlers (useEffect return or ngOnDestroy).
Can I use the IMA SDK within an iframe or AMP page?
Yes. The ima-sdk-web-iframe-mode.md file provides specific guidance for constrained environments where the standard integration pattern is restricted. This includes message-passing configurations and reduced API surface areas for AMP compatibility.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →