Back to Case Studies
Video Encoding

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
Client-Side Ad Insertion (CSAI) with SCTE-35 Marker Parsing & Multi-Platform Player Integration
Video Encoding
Domain
15
Technologies
6
Key Results
Delivered
Status

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 AVDateRangeMetadataGroup listener and IMA iOS SDK
  • Android Player: ExoPlayer with MetadataOutput listener 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-DATERANGE tags with SCTE35-OUT and SCTE35-IN attributes
  • Attributes include PLANNED-DURATION for ad break length and ID for event correlation
  • Preferred format for modern players (AVPlayer, ExoPlayer, Shaka)
EXT-X-CUE-OUT / EXT-X-CUE-IN (Legacy)
  • #EXT-X-CUE-OUT:DURATION= marks ad break start
  • #EXT-X-CUE-IN marks return to content
  • Supported for backward compatibility with older players and encoders

DASH Manifest Markers

  • SCTE-35 signals appear as elements in DASH MPD with schemeIdUri="urn:scte:scte35:2013:xml"
  • elements contain presentationTime, duration, and base64-encoded SCTE-35 binary payload
  • Shaka Player and ExoPlayer parse these natively via their event listener APIs

Marker Processing Flow

  1. Detection — Player metadata listener detects SCTE-35 cue event during manifest parsing
  2. Extraction — Break duration, event ID, and segmentation type extracted from the marker
  3. Ad Request — VAST/VMAP request fired to ad decision server with targeting parameters (content ID, genre, device type, user segment, geo)
  4. Pod Planning — Ad response parsed to build an ad pod (ordered list of ad creatives filling the break duration)
  5. Preload — Ad creatives preloaded during content playback to eliminate latency at ad break start
  6. Pause & Switch — Content playback paused at the cue point, player switches to ad playback
  7. Ad Playback — Ads played sequentially with quartile tracking, companion banner display, and click-through handling
  8. 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-DATERANGE metadata via textTrack cue 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.navigationMarkerGroups and AVDateRangeMetadataGroup used to detect SCTE-35 cues
  • AVPlayerItemMetadataOutput delegate fires on each cue event with parsed timing and payload
  • Google IMA iOS SDK handles VAST request and ad playback in a separate AVPlayer instance
  • 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() with MetadataOutput captures SCTE-35 events from HLS/DASH
  • Google IMA Android SDK integrated via ExoPlayer's ImaAdsLoader extension
  • Ad playback uses a separate MediaSource to 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 renderStitchedAd and renderTrackingEvent callbacks
  • Roku certification requires RAF usage — custom ad players are rejected during review
Fire TV (IMA SDK)
  • 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
Apple TV (AVKit + Custom)
  • AVPlayerViewController with interstitialTimeRanges for native ad break UI indicators
  • SCTE-35 cues parsed via AVPlayerItemMetadataCollector
  • Ad playback managed in a separate AVQueuePlayer for 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 Eventsimpression, 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

  1. Cross-Platform CSAI — Unified ad insertion across web, iOS, Android, Roku, Fire TV, and Apple TV
  2. SCTE-35 Client Parsing — HLS EXT-X-DATERANGE, CUE-OUT/IN, and DASH EventStream parsing
  3. Interactive Ads — Clickable overlays, companion banners, and skip buttons on all platforms
  4. Ad Pod Orchestration — Multi-ad break filling with waterfall, duration fitting, and deduplication
  5. Preloading — Ad creatives preloaded during content playback for zero-latency ad transitions
  6. Viewability Tracking — MOAT/IAS integration for premium ad buyer viewability requirements
  7. Connected TV Compliance — Roku RAF, Fire TV IMA, and Apple TV AVKit integrations meeting certification requirements
  8. Ad Blocker Resilience — Detection and fallback to first-party house ads on web

Results

Interactive Revenue: CSAI enabled clickable ads, unlocking 25% higher CPMs vs. SSAI-only inventory
Fill Rate: Waterfall demand with 3 ad sources achieved 92% pod fill rate across platforms
Viewer Experience: Ad preloading reduced ad break start latency to under 200ms
Platform Coverage: Unified CSAI deployed across 6 platforms with a shared ad orchestration core
Compliance: Passed Roku, Fire TV, and Apple TV ad framework certification on first submission
Viewability: 85%+ measured viewability rate, meeting premium advertiser thresholds

Technology Stack

Video.jsGoogle IMA SDKExoPlayerAVPlayerRoku Ad Framework (RAF)AWS Elemental MediaPackageAmazon CloudFrontSCTE-35HLSDASHVAST 4.2VMAPMOATNode.jsGoogle Ad Manager

Have a Similar Project in Mind?

Let's discuss how we can build a solution tailored to your needs.

Contact UsSchedule Appointment