Client-Side Ad Insertion (CSAI) with SCTE-35 Marker Parsing & Multi-Platform Player Integration
A video streaming platform needed to implement Client-Side Ad Insertion (CSAI) across web, mobile, and connected TV apps — enabling personalized, device-level ad experiences with full ad interaction support (clickable overlays, companion banners, skip buttons) that server-side insertion cannot provide.
Discuss Your Project
The Challenge
The platform was previously using SSAI (server-side ad insertion) exclusively, which handled monetization well but had significant limitations for interactive ad experiences:
- SSAI-stitched ads could not support clickable overlays, companion banners, or interactive ad units
- No ability to track client-side ad events (quartile progress, viewability, click-through) required by premium ad buyers
- Connected TV platforms (Roku, Fire TV, Apple TV) expected CSAI for their native ad frameworks and certification requirements
- SCTE-35 markers in HLS/DASH manifests needed to be parsed on the client, but each player SDK handled cue events differently
- Ad pod management (filling multi-slot ad breaks with multiple ads) required client-side orchestration
- Ad blocker detection and fallback logic were needed to protect revenue on web platforms
- Preloading ads without interrupting content buffer required careful player lifecycle management
Our Solution
We built a cross-platform CSAI framework with a unified ad orchestration layer that parses SCTE-35 markers from HLS/DASH manifests, communicates with VAST/VMAP ad servers, and manages ad playback lifecycle across web (Video.js/Shaka), iOS (AVPlayer), Android (ExoPlayer), and connected TV players.
Architecture
- Content Delivery: HLS/DASH streams with SCTE-35 markers via AWS MediaPackage + CloudFront
- Ad Decision Server: Google Ad Manager (GAM) / SpotX with VAST 4.2 and VMAP support
- Web Player: Video.js with custom SCTE-35 cue parser and Google IMA SDK integration
- iOS Player: AVPlayer with
AVDateRangeMetadataGrouplistener and IMA iOS SDK - Android Player: ExoPlayer with
MetadataOutputlistener and IMA Android SDK - Connected TV: Platform-native players (Roku RAF, Fire TV IMA, Apple TV AVKit) with ad framework adapters
- Ad Analytics: Custom event pipeline for impression, quartile, completion, click, and viewability tracking
- Fallback: Slate/house-ad delivery when ad fill is unavailable or ad blocker is detected
SCTE-35 Client-Side Parsing
HLS Manifest Markers
SCTE-35 signals appear in HLS manifests in two formats, both parsed by the client:
EXT-X-DATERANGE (HLS v7+)- Player listens for
#EXT-X-DATERANGEtags withSCTE35-OUTandSCTE35-INattributes - Attributes include
PLANNED-DURATIONfor ad break length andIDfor event correlation - Preferred format for modern players (AVPlayer, ExoPlayer, Shaka)
#EXT-X-CUE-OUT:DURATION=marks ad break start#EXT-X-CUE-INmarks return to content- Supported for backward compatibility with older players and encoders
DASH Manifest Markers
- SCTE-35 signals appear as
elements in DASH MPD withschemeIdUri="urn:scte:scte35:2013:xml" elements containpresentationTime,duration, and base64-encoded SCTE-35 binary payload- Shaka Player and ExoPlayer parse these natively via their event listener APIs
Marker Processing Flow
- Detection — Player metadata listener detects SCTE-35 cue event during manifest parsing
- Extraction — Break duration, event ID, and segmentation type extracted from the marker
- Ad Request — VAST/VMAP request fired to ad decision server with targeting parameters (content ID, genre, device type, user segment, geo)
- Pod Planning — Ad response parsed to build an ad pod (ordered list of ad creatives filling the break duration)
- Preload — Ad creatives preloaded during content playback to eliminate latency at ad break start
- Pause & Switch — Content playback paused at the cue point, player switches to ad playback
- Ad Playback — Ads played sequentially with quartile tracking, companion banner display, and click-through handling
- Resume — After pod completion, content playback resumes from the exact frame after the cue point
Platform-Specific Implementations
Web (Video.js + IMA SDK)
- Custom Video.js plugin intercepts
#EXT-X-DATERANGEmetadata viatextTrackcue change events - Google IMA HTML5 SDK manages VAST ad requests, ad playback, and companion rendering
- Ad container overlay positioned above the video element for click-through and skip button support
- Ad blocker detection via canary request — falls back to house ads or content-resumption on detection
- Preroll, midroll, and postroll support via VMAP or manual cue-point scheduling
iOS (AVPlayer + IMA SDK)
AVPlayerItem.navigationMarkerGroupsandAVDateRangeMetadataGroupused to detect SCTE-35 cuesAVPlayerItemMetadataOutputdelegate fires on each cue event with parsed timing and payload- Google IMA iOS SDK handles VAST request and ad playback in a separate
AVPlayerinstance - Picture-in-Picture (PiP) paused during ad breaks per platform ad policy
- Background audio handled — ads do not play in background mode
Android (ExoPlayer + IMA SDK)
Player.Listener.onMetadata()withMetadataOutputcaptures SCTE-35 events from HLS/DASH- Google IMA Android SDK integrated via ExoPlayer's
ImaAdsLoaderextension - Ad playback uses a separate
MediaSourceto avoid polluting the content buffer - Handles Activity lifecycle — ad state preserved across configuration changes and backgrounding
- Android TV and mobile share the same ad logic with UI-layer adaptations
Connected TV Platforms
Roku (RAF — Roku Ad Framework)- Roku's native RAF library parses SCTE-35 markers from HLS manifests directly
RAF.setAdUrl()configured with VAST endpoint; RAF handles ad request, pod building, and playback- Companion ad support via RAF's
renderStitchedAdandrenderTrackingEventcallbacks - Roku certification requires RAF usage — custom ad players are rejected during review
- Uses Android ExoPlayer + IMA SDK implementation adapted for Fire TV's Leanback UI
- D-pad navigation for skip button and "Learn More" click-through on ad overlays
- Fire TV Ad ID used for ad targeting in VAST requests
AVPlayerViewControllerwithinterstitialTimeRangesfor native ad break UI indicators- SCTE-35 cues parsed via
AVPlayerItemMetadataCollector - Ad playback managed in a separate
AVQueuePlayerfor clean content/ad separation - tvOS remote click handler for interactive ad elements
Ad Pod Management
- Pod Filling — Multiple VAST ads assembled to fill the signaled break duration
- Waterfall — If primary ad server returns no-fill, secondary/tertiary demand sources queried sequentially
- Duration Fitting — Pod builder selects ad combinations that fit within break duration (±0.5s tolerance)
- Deduplication — Same ad creative not shown twice in a single pod
- Frequency Capping — Per-user, per-session caps enforced client-side to avoid ad fatigue
- Bumpering — Short bumper creatives ("We'll be right back" / "Welcome back") wrap ad pods
Ad Event Tracking & Analytics
- Standard VAST Events —
impression,start,firstQuartile,midpoint,thirdQuartile,complete,skip,clickThrough - Viewability — MOAT/IAS viewability pixels fired based on ad viewport visibility and duration thresholds
- Custom Events — App-level events (ad break start/end, pod fill rate, preload timing, fallback triggered)
- Server Pipeline — Client fires events to a lightweight event collector, which fans out to GAM, MOAT, and the internal analytics warehouse
- Reconciliation — Server-side log reconciliation with client-side events for discrepancy detection
Ad Blocker Handling (Web)
- Detection — Canary VAST request to a known ad domain; timeout or block indicates ad blocker
- Fallback Strategy — Serve house ads or promotional trailers from first-party CDN domain
- Content Gating — Optional soft gate: prompt user to whitelist the site before content plays
- Analytics — Ad blocker detection rate tracked per browser, geography, and page
Key Features
- Cross-Platform CSAI — Unified ad insertion across web, iOS, Android, Roku, Fire TV, and Apple TV
- SCTE-35 Client Parsing — HLS
EXT-X-DATERANGE,CUE-OUT/IN, and DASHEventStreamparsing - Interactive Ads — Clickable overlays, companion banners, and skip buttons on all platforms
- Ad Pod Orchestration — Multi-ad break filling with waterfall, duration fitting, and deduplication
- Preloading — Ad creatives preloaded during content playback for zero-latency ad transitions
- Viewability Tracking — MOAT/IAS integration for premium ad buyer viewability requirements
- Connected TV Compliance — Roku RAF, Fire TV IMA, and Apple TV AVKit integrations meeting certification requirements
- Ad Blocker Resilience — Detection and fallback to first-party house ads on web
Results
Technology Stack
More Case Studies
Explore more of our technical implementations
SCTE-35 Ad Marker Signaling & Media Trailer Insertion Pipeline
A streaming media company needed a robust, automated pipeline for injecting SCTE-35 ad markers into live and VOD streams, along with the ability to insert promotional trailers (pre-roll, mid-roll, and post-roll) at precisely timed positions — enabling monetization across FAST channels, live events, and on-demand content libraries.
AWS Media Services for FAST Channel Streaming over SRT
A media company needed to establish reliable, low-latency contribution feeds for their FAST channels using the Secure Reliable Transport (SRT) protocol — enabling high-quality content ingest from remote studios, cloud playout systems, and syndication partners over unpredictable internet connections.
AWS Media Services for FAST Channel Streaming over HLS
A media company needed to launch Free Ad-Supported Streaming Television (FAST) channels — 24/7 linear streams of curated video content delivered over HLS to smart TVs, set-top boxes, and web/mobile players, monetized through programmatic ad insertion.
Have a Similar Project in Mind?
Let's discuss how we can build a solution tailored to your needs.