Frontend Integration of Nonlinear Ads for VOD with Google IMA
Author
Alexian Kauffmann
Date Published
Video-on-demand platforms using server-side ad insertion (SSAI) are increasingly extending beyond traditional linear ad pods. Nonlinear formats such as overlays introduce additional ad placements between breaks and enable richer creative formats like interactive lower-thirds or corner placements.
A practical approach combines server-side and client-side responsibilities:
- Linear ad pods remain server-side for resilience, ad-blocker resistance, and a consistent playback experience, typically delivered through AWS Elemental MediaTailor.
- Nonlinear ads are handled on the frontend using Google Ad Manager and the Google IMA SDK, rendering overlays synchronized with the VOD stream without modifying HLS manifests or segment delivery.
The sections that follow outline an end-to-end integration approach, covering ad server configuration, HLS signaling, player integration, enforcement logic, and operational considerations.
Why Split Linear and Nonlinear Between SSAI and IMA
Distributing linear and nonlinear ads across server and client layers establishes a clear separation of responsibilities.
- SSAI (linear)
- Handles pre-roll, mid-roll, post-roll pods.
- Maintains stable, DRM-compatible manifests.
- Reduces ad-blocker exposure by stitching ads directly into the stream.
- Front-end IMA (nonlinear)
- Renders interactive and clickable overlays.
- Leverages Google Ad Manager’s display and reporting capabilities.
- Operates in a dedicated channel (vad_type=nonlinear), preventing conflicts with linear demand.
This separation enables:
- Reuse of existing Google Ad Manager configurations while segmenting inventory by format.
- Independent iteration on overlay formats (companions, interactive units, sponsorship placements) without changes to SSAI infrastructure.
- A predictable playback pipeline, where the player consumes a MediaTailor-personalized manifest and overlays augment the experience without altering core delivery.
Google Ad Manager Setup for Nonlinear Overlays
Proper configuration in Google Ad Manager is a prerequisite for serving nonlinear overlays in a VOD workflow.
Propagation Delay: Plan for ~30 Minutes
Most changes in Google Ad Manager, including orders, line items, targeting rules, creative assignments, and status updates, require time to propagate across the ad serving network.
For debugging and QA:
- Apply configuration changes.
- Allow approximately 30 minutes for propagation.
- Avoid rapid “change → refresh” cycles, as they typically reflect stale state rather than actual behavior.
Ad Units, Sizes, and Line Items
Create or reuse a video ad unit
Within Google Ad Manager:
- Navigate to Inventory → Ad units → New ad unit.
- Define a clear hierarchy (for example: /1234567/vod/app-name).
- Under Sizes, configure Video or audio (VAST) sizes requested by clients. For most SSAI and overlay use cases, a 640×480 size is sufficient for both linear and nonlinear demand.
Generate the ad tag URL
- Open the Tags tab.
- Select Google Publisher Tag for video and audio.
- Complete the tag generation flow.
The resulting VAST tag includes key parameters:
- iu= identifies the ad unit path.
- sz= specifies the requested size (for example, 640x480).
Orders, line items, and size targeting
Create orders and line items aligned with overlay demand and associated advertisers.
Ensure the following:
- Line items target the correct ad unit or a parent in the hierarchy.
- Creative sizes match the configured ad unit size, for example 640×480.
Size targeting determines eligibility. A mismatch between the requested size (sz) and configured creatives leads to under-delivery or empty responses.
Two Tags, Two Roles: SSAI vs Frontend
In this architecture, two VAST tags are typically defined for the same inventory family, each serving a distinct purpose.
Server-Side (SSAI) Tag for Linear Ads
Used by AWS Elemental MediaTailor or an equivalent SSAI solution to deliver stitched linear ads.
Hostname
https://serverside.doubleclick.net/gampad/ads
Key query parameters
- iu=/1234567/vod/app-name
- sz=640x480
- ssss=mediatailor indicates the request originates from MediaTailor SSAI
- vad_type=linear restricts responses to linear creatives
- output=vast&env=vp defines a standard video player environment
This tag is invoked exclusively by the SSAI layer and is never called directly from the browser.
Frontend Tag for Nonlinear Ads
Used in the browser through the Google IMA SDK to request overlay creatives from Google Ad Manager.
Hostname
https://pubads.g.doubleclick.net/gampad/ads
Key query parameters
- iu=/1234567/vod/app-name
- sz=640x480
- vad_type=nonlinear restricts responses to overlay creatives
- description_url=https://example-vod.com/watch/123 optional, useful for contextual targeting and reporting
- gdfp_req=1&unviewed_position_start=1&output=vast&env=vp standard video request parameters
Separation of Responsibilities
Fixing vad_type=linear for SSAI and vad_type=nonlinear for the frontend ensures a clean split:
- Server-side components handle stitched ad pods within the stream.
- The IMA SDK handles overlay inventory only.
- Both rely on the same ad unit structure and can be managed centrally in Google Ad Manager.
Frontend Configuration
A common approach is to inject the nonlinear ad tag through an environment variable:
1VITE_GOOGLE_IMA_AD_TAG_URL=https://pubads.g.doubleclick.net/gampad/ads?iu=...&sz=640x480&vad_type=nonlinear&...
How Overlay Opportunities Reach the Player: HLS Markers
Overlay timing is driven by markers embedded directly in the HLS manifest. These markers indicate when overlays should appear during playback and allow the player to synchronize rendering with the video timeline.
ESAM, SPN, MCCN, and Custom Tags (Backend Perspective)
On the transcoding side, a common approach combines AWS Elemental MediaConvert with ESAM using two XML documents:
SignalProcessingNotification (SPN)
- Specifies timing of ad events using sig:NPTPoint@nptPoint in seconds.
- Describes event type using SCTE-35 descriptors such as segmentation descriptors.
ManifestConfirmConditionNotification (MCCN)
- Uses ManifestResponse entries to modify the HLS output.
- Controls which tags are inserted, such as #EXT-X-CUE-OUT, #EXT-X-CUE-IN, or custom tags.
For overlay use cases, MCCN can instruct MediaConvert to emit a custom tag such as:
- #EXT-X-OVERLAY-AD:ID="1",DURATION=5.0
Key constraints:
- acquisitionPointIdentity and acquisitionSignalID must match between SPN and MCCN.
- If these identifiers do not align, the manifest is not modified.
- Timing is controlled by SPN through nptPoint.
- Tag structure and content are defined by MCCN.
Linear Ad Markers in VOD
When working with AWS Elemental MediaTailor for VOD, a common pattern is to use:
- #EXT-X-CUE-OUT:0
- #EXT-X-CUE-IN
Using CUE-OUT:0 prevents unintended skipping of main content in a VOD context.
What the Frontend Needs
From a frontend perspective, the underlying complexity reduces to a simple contract: the HLS manifest contains overlay markers that define when and how overlays should appear.
Example markers:
- #EXT-X-OVERLAY-AD:ID="1",DURATION=5.0
- #EXT-X-OVERLAY-AD:ID="2",DURATION=8.0
Each marker provides:
- A unique identifier
- A duration in seconds
- A position aligned with a segment boundary, which maps to a playback timestamp
Frontend Responsibilities
The player integration is responsible for:
- Parsing the HLS manifest to extract overlay markers
- Building a structured registry of overlay opportunities, for example: overlay = { id, startTime, duration }
- Using this registry to trigger ad requests via the Google IMA SDK and control overlay rendering
This abstraction allows the frontend to operate independently of the underlying ESAM and transcoding logic, relying only on the presence and consistency of manifest markers.
Architectural Blueprint: Detection, Resolution, Presentation
A robust overlay integration can be organized into three distinct layers, each with a clearly defined role:
Layer | Responsibility | Key Components |
|---|---|---|
Detection | Identify overlay opportunities in the stream | HLS manifest parser, Video.js (or similar) integration |
Resolution | Fetch overlay creatives and prepare them for rendering | Google IMA SDK, AdsLoader, AdsManager mapping |
Presentation | Render overlays and enforce timing & behavior | Overlay container, AdDisplayContainer, control logic |
This layered approach provides several advantages:
- Testability: Each layer can be validated independently, for example by mocking manifest parsing or IMA responses.
- Flexibility: Player implementations, prefetch strategies, and UI components can evolve without affecting the rest of the system.
- Resilience: Failures remain isolated within a layer, allowing the system to degrade gracefully instead of breaking end-to-end.
Detection Layer: From HLS Manifests to Overlay Markers
The Detection layer converts raw HLS manifests into a structured set of overlay opportunities that can be consumed by the rest of the system.
Parsing MediaTailor Manifests
In a typical VOD player stack:
- A player such as Video.js with VHS (Video.js HTTP Streaming), or another HLS-compatible library, is used.
- The player requests a personalized manifest from AWS Elemental MediaTailor.
This manifest includes:
- Linear ad markers such as #EXT-X-CUE-OUT:0 and #EXT-X-CUE-IN
- Overlay markers such as #EXT-X-OVERLAY-AD:...
Detecting Overlay Markers
Overlay detection requires integration with the HLS playlist loading pipeline:
- Hook into playlist loading events, such as VHS playlist loader events or equivalent mechanisms in other players.
- When a playlist is fetched, whether master or media, inspect its contents as text.
- Scan for #EXT-X-OVERLAY-AD tags.
Each marker is parsed into a structured representation, for example:
1type OverlayMarker = {2 id: string;3 startTime: number; // seconds, derived from segment index or EXTINF sums4 duration: number; // seconds, from the DURATION attribute5};
Maintain a registry of markers, such as a Map<string, OverlayMarker>, keyed by marker ID.
Segment Alignment and Timing
Overlay markers are typically aligned with segment boundaries. For example, a marker at 360 seconds with 6-second segments corresponds to the segment starting at 360 seconds.
The startTime can be derived in two ways:
- By summing #EXTINF durations up to the target segment
- By using segment timing metadata already computed by the playlist loader
This structured representation enables precise detection of overlay windows during playback.
Integration with the Video Player
Once a registry of overlay markers is available, the player is responsible for translating playback position into overlay events.
Playback Event Handling
Subscribe to playback time updates, for example the timeupdate event in Video.js.
On each update:
- Read currentTime.
- Check whether playback has entered a marker window defined by [startTime, startTime + duration].
Triggering Overlay Lifecycle Events
When playback enters a marker window:
- Notify the Resolution and Presentation layers that an overlay should be displayed.
When playback leaves a marker window:
- Trigger teardown of the overlay if it is still active.
Overlay Scheduler Abstraction
This logic can be encapsulated in a simple overlay scheduler:
- Accepts the list of overlay markers
- Emits events such as overlaywindowstart(marker) and overlaywindowend(marker)
Other parts of the system subscribe to these events to start and stop overlays in a consistent and decoupled manner.
Resolution Layer: Prefetching Nonlinear Ads with IMA
The Resolution layer uses the Google IMA SDK to prefetch nonlinear ads for each overlay marker as soon as the manifest is parsed. This ensures that creatives are ready when playback reaches the corresponding timestamps.
Loading the Google IMA SDK
The IMA SDK must be loaded into the application before any ad requests are made:
1<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
In single-page applications or module-based setups, the script can be injected dynamically. A small wrapper can then expose a promise that resolves once google.ima becomes available, ensuring the rest of the integration executes only after the SDK is ready.
Ad Tag Configuration via Environment
The nonlinear ad tag is typically provided through an environment variable, such as VITE_GOOGLE_IMA_AD_TAG_URL or an equivalent mechanism:
1const NONLINEAR_AD_TAG_URL = import.meta.env.VITE_GOOGLE_IMA_AD_TAG_URL;
This approach keeps the codebase consistent across environments such as development, staging, and production, while allowing the ad tag to be managed and updated centrally.
AdsLoader, AdDisplayContainer, and AdsManager
The Google IMA SDK relies on three core components:
AdDisplayContainer
- Binds an HTML container to a video element and serves as the rendering surface for ads.
- On many platforms, initialization must occur in response to a user interaction, such as the first play event.
AdsLoader
- Handles ad requests to Google Ad Manager.
- Emits ADS_MANAGER_LOADED when creatives are available.
AdsManager
- Controls the lifecycle and rendering of ad creatives.
- For nonlinear ads, rendering occurs within the display container without interrupting the main content.
Recommended Structure for Overlays
For overlay-based integrations, a consistent structure helps simplify lifecycle management:
- A single shared AdDisplayContainer positioned above the player
- A single shared AdsLoader instance
- One AdsManager per overlay marker, created in advance and stored until its playback window is reached
Nonlinear-Only Requests: Zero Linear Slot
To prevent linear ads from being returned in the overlay channel, each ad request must explicitly disable the linear slot and define only the nonlinear slot.
This is achieved by setting the linear slot dimensions to zero and specifying dimensions for the nonlinear slot:
- linearAdSlotWidth = 0
- linearAdSlotHeight = 0
- nonLinearAdSlotWidth = overlayWidth
- nonLinearAdSlotHeight = overlayHeight
In pseudo-code:
1const request = new google.ima.AdsRequest();2request.adTagUrl = NONLINEAR_AD_TAG_URL;34request.linearAdSlotWidth = 0;5request.linearAdSlotHeight = 0;67request.nonLinearAdSlotWidth = overlayWidth;8request.nonLinearAdSlotHeight = overlayHeight;
When combined with vad_type=nonlinear in the ad tag, this configuration ensures that the Google IMA SDK returns only nonlinear creatives.
Prefetch Strategy Per Overlay Marker
Once the manifest is parsed and all overlay markers are available:
- Iterate over markers and issue one AdsRequest per marker.
- Store the resulting AdsManager in a registry keyed by marker ID.
High-level flow:
- For each OverlayMarker:
- Create an AdsRequest.
- Call adsLoader.requestAds(request).
- On ADS_MANAGER_LOADED:
- Retrieve the AdsManager.
- Associate it with the corresponding marker, for example in a map or queue.
- If IMA signals an error or no-fill:
- Mark the marker as “empty” so the Presentation layer can skip it silently.
This prefetching:
- Hides network latency from the user, as ads are ready when playback reaches each marker.
- Allows validation of inventory availability and graceful fallback when needed.
Manifest Changes and Cleanup
When the VOD asset or manifest changes, for example when a different episode or quality profile is selected:
- Clear the overlay marker registry.
- Destroy all existing AdsManager instances.
- Reset any internal queues in the Overlay Ad Manager.
This prevents:
- Orphaned overlay requests tied to previous content.
- Memory leaks caused by abandoned AdsManagers.
Presentation Layer: Overlay Display and Timing Enforcement
The Presentation layer orchestrates:
- When an overlay ad actually starts.
- How it is rendered and hidden.
- How user interactions are handled.
Overlay UI Container
Implement a fixed container above the video element, for example:
- A <div> absolutely positioned over the video.
- Sized to match the overlay slot, such as the bottom third of the player.
- Initially hidden, but kept in the DOM at all times.
The Google IMA SDK injects its own DOM into this container via the AdDisplayContainer. To ensure stable behavior:
- Avoid re-creating or removing the container while an overlay may be active
- Control visibility using CSS classes, for example .is-visible
Initializing IMA on User Interaction
On the first playback attempt, for example a play button click:
- Call adDisplayContainer.initialize() to meet autoplay policy requirements.
- Optionally initialize IMA state for subsequent overlay playback
This step is critical on mobile devices. Without initialization tied to a user gesture, some platforms block ad playback from the Google IMA SDK.
Starting an Overlay When Its Marker Fires
When the Detection layer signals that playback has entered a marker window:
- Retrieve the corresponding AdsManager from the registry.
- If not yet initialized, call adsManager.init(width, height, viewMode, videoDuration).
- Call adsManager.start() to render the nonlinear ad.
Optional event handling:
- Listen for events such as:
- google.ima.AdEvent.Type.STARTED
- google.ima.AdEvent.Type.COMPLETE
- google.ima.AdErrorEvent.Type.AD_ERROR
- Log or instrument these events for reporting and debugging.
Enforcing Marker Duration vs VAST Timing
To maintain a consistent user experience, overlay lifespan should be driven by the marker duration rather than the VAST-defined duration.
For example, if a marker specifies DURATION=5.0:
- Track playback time relative to the marker window
When currentTime >= marker.startTime + marker.duration:
- Force teardown using adsManager.stop() and or adsManager.destroy()
- Hide the overlay container
This ensures:
- Overlays do not extend beyond their intended position in the timeline
- Shorter creatives remain visible for the full marker window, unless explicitly closed earlier
Alternatively, overlays can be closed on COMPLETE, treating the marker duration as a maximum window rather than a fixed duration.
Handling User Interactions
The Google IMA SDK renders its own interactive elements, including click targets, timers, and in some cases a close button. The surrounding implementation is responsible for ensuring that these elements behave correctly within the player.
Ensure the overlay container:
- Accepts pointer events
- Does not interfere with core playback controls beyond what is necessary
- Optionally dims or mutes underlying UI elements if required by the design
Ad measurability should also be preserved. The overlay should remain unobstructed during its display window.
Multiple Overlays and Overlaps
If the manifest includes multiple overlay markers:
- Define a clear policy for overlapping windows, either by disallowing overlaps or establishing precedence
The Overlay Ad Manager can then implement one of the following strategies:
- Queue overlays and display them sequentially
- Ignore new overlays while another is active
- Support multiple simultaneous placements if the UI provides distinct regions
Enforcing Non-Skippable Linear Ad Breaks
Nonlinear overlays are handled through the Google IMA SDK, while linear ad breaks remain under the control of the SSAI pipeline. Preventing users from skipping these breaks through timeline scrubbing is often required.
A dedicated ad break enforcement subsystem can handle this using metadata provided by AWS Elemental MediaTailor.
Detection: Metadata Track “ad-cues”
MediaTailor can inject a metadata track into the HLS manifest that describes ad breaks. On the client side:
- Scan the tracks for one labeled "ad-cues" or a similar identifier
- Listen for cuechange events on that track.
- Parse cue payloads into structured objects, for example:
- adStartTime
- adEndTime
Maintain a registry of ad breaks, similar to the overlay marker registry.
Tracking: Ad Break State
Two inputs are used to determine whether playback is inside an ad break:
- Metadata cues defining start and end times
- Playback updates from the player, such as timeupdate
Using these, evaluate whether currentTime falls within any ad break window and track state per break:
- pending
- inProgress
- completed
Update this state continuously as playback progresses.
Enforcement: Disabling Seek During Ads
When playback enters a linear ad break:
- Disable or lock the seek bar
- Optionally indicate the ad segment visually, for example with a dimmed or restricted scrub bar
- Reject programmatic seek attempts, including keyboard shortcuts or external controls
When playback exits the ad break:
- Re-enable seeking
- Restore normal player controls
Interaction with Overlays
This enforcement operates independently of the overlay system, but ensures:
- Linear ad breaks cannot be skipped
- Overlays do not become a workaround for bypassing ads
Overlay display can also be gated based on ad break state, for example by suppressing overlays during linear pods to maintain a clear and focused user experience.
Putting It All Together: Data Flow for Nonlinear Overlays
End-to-end data flow for a VOD session with overlays:
1. Playback Start
- The player loads a personalized HLS manifest from AWS Elemental MediaTailor
- Video playback begins, including core content and server-side linear ads
2. Overlay Detection
- The HLS manifest is parsed as playlists are loaded
- #EXT-X-OVERLAY-AD tags are extracted and converted into OverlayMarker entries
3. IMA Prefetch
For each marker, the Resolution layer:
- Issues a nonlinear AdsRequest using the configured ad tag
- Stores the resulting AdsManager instance mapped to the marker
4. Overlay Presentation
When playback reaches startTime:
- The overlay scheduler emits overlaywindowstart(marker)
- The Overlay Ad Manager initializes and starts the corresponding AdsManager
- The overlay container is displayed
When playback passes startTime + duration:
- The overlay is stopped or destroyed
- The container is hidden
5. Linear Ad Enforcement
- Metadata-driven logic disables seeking during server-side ad breaks
- Overlay behavior during these periods can be enabled or suppressed based on UX decisions
Testing, QA, and Observability
Reliable operation requires consistent testing and telemetry across all layers of the integration.
Functional and Integration Testing
Manifest-level tests
- Verify that HLS playlists include #EXT-X-OVERLAY-AD tags at the expected timestamps
- Validate that DURATION values and marker IDs are correctly formed
Player integration
- Unit test the manifest parser and overlay scheduler
- Use synthetic manifests and controlled playhead timelines to confirm that overlay window events are triggered at the correct moments
IMA integration
In a staging network within Google Ad Manager or using test line items:
- Confirm that requests with vad_type=nonlinear return overlay creatives
- Log key events such as ADS_MANAGER_LOADED, STARTED, COMPLETE, and error events from the Google IMA SDK
Ad break enforcement
- Use synthetic metadata tracks to simulate ad breaks
- Verify that seek controls are correctly locked and restored at the appropriate times
Observability
Instrument each layer of the system to monitor performance and detect issues early:
Detection
- Number of overlay markers per asset
- Fraction of markers that result in an overlay ad, reflecting fill rate
Resolution
- Ad request latency and error rates from the Google IMA SDK
- No-fill rate for nonlinear inventory
Presentation
- Viewable impressions and click-through rates reported via Google Ad Manager
- User-reported issues or anomalies captured in session logs
Additionally, track:
- Timeouts or race conditions between manifest parsing and ad prefetch
- Performance impact of overlay rendering, particularly on lower-end devices
Common Pitfalls and How to Avoid Them
Missing or mismatched ESAM IDs
- Symptom: #EXT-X-OVERLAY-AD tags do not appear in the HLS manifest
- Fix: Ensure acquisitionPointIdentity and acquisitionSignalID match between SPN and MCCN for each overlay event
Incorrect GAM size or targeting
- Symptom: IMA requests succeed but return no ads
- Fix: Align the sz parameter with ad unit and creative sizes, and confirm that line items target the correct inventory in Google Ad Manager
Missing vad_type=nonlinear or zero-size linear slot
- Symptom: Linear ads are returned through IMA, or overlays conflict with SSAI pods
- Fix: Set vad_type=nonlinear in the tag and configure linearAdSlotWidth and linearAdSlotHeight to zero in the Google IMA SDK request
AdDisplayContainer not initialized via user interaction
- Symptom: Overlays fail to render on mobile or are blocked
- Fix: Call adDisplayContainer.initialize() in response to a user action, such as the first playback event
Overlay duration tied only to VAST
- Symptom: Overlays persist too long or disappear earlier than intended
- Fix: Use the manifest marker DURATION as the authoritative window and treat VAST timing as advisory
Missing cleanup on manifest change
- Symptom: Overlays from previous content appear on new playback sessions
- Fix: Destroy AdsManager instances and clear registries when switching assets
Weak seek enforcement
- Symptom: Users can skip server-side ad breaks by scrubbing
- Fix: Use metadata-driven ad break detection to lock and restore seeking at the correct times
Outcomes and Best Practices
A well-executed integration of the Google IMA SDK for nonlinear VOD overlays, combined with SSAI for linear ads, delivers several key benefits:
Richer monetization
- Additional inventory without increasing the number or duration of linear ad pods
- Flexible placement for sponsorships, promotions, and interactive creatives
Clear separation of responsibilities
- Backend systems handle transcoding, ad markers, and SSAI
- Frontend systems handle overlay rendering and user interaction
- Google Ad Manager and IMA provide unified measurement and control
Predictable user experience
- Enforced, non-skippable linear ad breaks
- Time-bounded overlays aligned with content
- Stable behavior across varying bandwidth and device conditions
To ensure long-term reliability and maintainability:
- Treat manifest markers, ad tags, and IMA configuration as contracts, and document them clearly
- Encapsulate Detection, Resolution, and Presentation layers behind well-defined interfaces
- Monitor overlay performance and error rates alongside core playback metrics
With these practices in place, frontend integration of the Google IMA SDK for nonlinear ads becomes a stable and extensible component of a VOD platform, capable of evolving alongside changes in creative formats, ad strategies, and playback environments.
Conclusion
Nonlinear overlays extend monetization without disrupting core playback, but require careful coordination between manifest signaling, ad serving, and player logic. A structured approach across detection, resolution, and presentation ensures predictable behavior and simplifies iteration. When implemented with clear contracts and observability, this pattern supports scalable, maintainable growth in both ad formats and user experience.
