Exposed Ad

API for displaying ad units from the host application. Singleton object, available after StreamLayer.initializeApp(...) is called.

Quick Start

// Requires a coroutine scope — show functions are suspend
lifecycleScope.launch {
    StreamLayerAd.standard11 {
        contentImage("https://cdn.example.com/banner.jpg")
        buttonSimple("Learn more", "https://example.com")
    }
}

Ad Unit Types

standard11 — 1:1 banner

Aspect ratio 1:1. Does not support text content (title/description).

suspend fun standard11(block: Builder.NoTextContent.() -> Unit): Result<Unit>

Supported interfaces: ContentHeader, ContentImage, ContentVideo, ContentLBar, ContentBackground, ContentButton, ContentResumeButton, ViewMode, FullViewMode, Settings

Examples:

// Image in SideBar mode (default)
StreamLayerAd.standard11 {
    sponsorImageUrl = "https://cdn.example.com/sponsor.png"
    headerText = "Sponsor"
    contentImage("https://cdn.example.com/ad.jpg")
    buttonSimple("Go", "https://example.com", iconUrl = null)
}

// Video in Overlay mode with a 3-second delay
StreamLayerAd.standard11 {
    contentVideo("https://cdn.example.com/ad.mp4", "https://cdn.example.com/thumb.jpg")
    viewOverlay()
    delay(3_000L)
}

// LBar
StreamLayerAd.standard11 {
    contentLBar("https://cdn.example.com/lbar.jpg", "https://example.com")
    viewLBar()
}

// Full screen mode
StreamLayerAd.standard11 {
    contentImage("https://cdn.example.com/full.jpg")
    viewFullScreen()
    resumeButtonText()
}

standard21 — 2:1 banner with text

Aspect ratio 2:1. Additionally supports titleText and descriptionText.

suspend fun standard21(block: Builder.WithTextContent.() -> Unit): Result<Unit>

Supported interfaces: everything from standard11, plus ContentText

Examples:

// Image with text
StreamLayerAd.standard21 {
    sponsorImageUrl = "https://cdn.example.com/sponsor.png"
    headerText = "Match partner"
    titleText = "Special offer"
    descriptionText = "Today only — 30% off"
    contentImage("https://cdn.example.com/banner.jpg")
    buttonSimple("Buy", "https://shop.example.com")
    backgroundImageRemote(
        portraitUrl = "https://cdn.example.com/bg_portrait.jpg",
        landscapeUrl = "https://cdn.example.com/bg_landscape.jpg"
    )
}

// Video with return-to-video button
StreamLayerAd.standard21 {
    titleText = "Don't miss it!"
    contentVideo("https://cdn.example.com/promo.mp4")
    buttonReturnToVideo()
    resumeButtonImage()
}

fullScreen — full-screen ad

Supports Picture-in-Picture (default) and Side-by-Side modes.

suspend fun fullScreen(block: Builder.FullScreen.() -> Unit): Result<Unit>

Supported interfaces: ContentHeader, ContentText, ContentVideo, ContentBackground, ContentButton, ContentResumeButton, Settings

View mode methods:

MethodDescription
viewPictureNPicture()Picture-in-Picture (default)
viewSideBySide()Video side by side with the ad

Examples:

// Picture-in-Picture with video ad
StreamLayerAd.fullScreen {
    sponsorImageUrl = "https://cdn.example.com/logo.png"
    headerText = "Title sponsor"
    titleText = "Advertisement"
    descriptionText = "Check out our new product"
    contentVideo("https://cdn.example.com/vast_video.mp4")
    resumeButtonText()
    viewPictureNPicture()
}

// Side-by-Side with transparent background and back press override
StreamLayerAd.fullScreen {
    contentVideo("https://cdn.example.com/ad.mp4")
    viewSideBySide()
    backgroundTransparent()
    overrideBackPressed {
        // called instead of the default close action on Back press
        analyticsTracker.trackAdDismissed()
    }
}

Note: when viewFullScreen() (from FullViewMode) is used with GooglePal, only image mode is available (AdContentType.Image_Only). For standard11/standard21, viewFullScreen() switches the overlay to FullBleed mode.


googlePal — Google PAL VAST/WebView ad

suspend fun googlePal(block: Builder.GooglePal.() -> Unit): Result<Unit>

GooglePal-specific methods:

MethodDescription
contentVastUrl(url)VAST/VMAP URL to fetch the ad from
setupPrefetch(time)Enable prefetching with a refresh interval of time ms (default 60 min)
showPrefetchedAd()Display a previously prefetched ad
stopPrefetchAd()Stop prefetching
webView { ... }Display ad via WebView with query parameters

Supported interfaces: ViewMode, FullViewMode, ContentResumeButton, Settings

VAST ads — Server-fetched static image ads via the SDK's external pause ad store GPT ads — Google Publisher Tag ads loaded in a sandboxed iframe via StreamLayer's ad host

VAST ad with prefetching

// Set up prefetching (call at session start)
StreamLayerAd.googlePal {
    contentVastUrl("https://pubads.g.doubleclick.net/gampad/ads?...")
    setupPrefetch(60 * 60 * 1000L) // refresh every hour
    viewFullScreen()
    resumeButtonText()
}

// Show prefetched ad on player pause
StreamLayerAd.googlePal {
    showPrefetchedAd()
}

// Stop prefetching (call at session end)
StreamLayerAd.googlePal {
    stopPrefetchAd()
}

WebView ad

StreamLayerAd.googlePal {
    webView {
        host = "https://ads.example.com/ad"
        url = "https://pubads.g.doubleclick.net/gampad/ads?..."
        brand = "ExampleBrand"
        product = "sport_app"
        content = "live_stream"
        platform = "cotv"
        platformtype = "androidtv"
        pagetype = "playerpage"
        slot = "pause_ad_slot"
        width = 320
        height = 480
        npa = 0      // non-personalized ads (0 = personalized, 1 = non-personalized)
        islat = 0    // limited ad tracking (0 = not limited)
    }
    viewFullScreen()
}

UrlBuilder parameters:

ParameterTypeDescription
hostStringRequired. Base URL of the ad server, will be providen for you.
urlString?Required. VAST URL, GPT URL (output=ldjh), or GPT slot ID (non-HTTP path)
brandString?Brand name
productString?Product identifier (e.g., tsn). Used for ad unit path building
contentString?Content identifier (e.g., cfl-news-and-highlights). Used for ad unit path building
platformString?Platform identifier (e.g., cotv). Used for ad unit path building
platformtypeString?Platform type (e.g., androidtv, amazonfire, googletv). Used for ad unit path building
pagetypeString?Page type (e.g., playerpage). Used for ad unit path building
revshareString?Revenue share identifier
npaInt?Non-personalized ads flag (1 = non-personalized). When npa=1, permutive targeting keys are stripped
targetString?Custom GPT key-value targeting pairs (passed as t= param to the ad host)
islatInt?Limit ad tracking flag (1 = limited)
widthInt?Ad unit width
heightInt?Ad unit height
slotString?Ad slot identifier

The SDK automatically appends rdid (device advertising ID) and idtype=adid to the URL.


Common Settings (Builder.Settings)

Available for all ad types.

// Show delay in milliseconds
delay(5_000L) // show after 5 seconds

// Override Back press — host will receive ActionClicked.Source.BACK_BUTTON
overrideBackPressed()

// Override Back press with a custom action (called instead of the default)
overrideBackPressed {
    // StreamLayerAd.hide() can be called manually here
}

When overrideBackPressed() is active, the host receives onActionClicked(ActionClicked(Source.BACK_BUTTON)) via SLRAppHost.


View Modes (ViewMode / FullViewMode)

MethodTypeDescription
viewOverlay()ViewModeOverlay on top of the video
viewSideBar()ViewModeSide bar (default)
viewLBar()ViewModeL-shaped banner
viewFullScreen()FullViewModeFull screen mode (FullBleed)
viewPictureNPicture()FullScreen onlyPicture-in-Picture
viewSideBySide()FullScreen onlySide-by-Side

Resume Button (ContentResumeButton)

// Text button labeled "RESUME"
resumeButtonText()

// Play icon button
resumeButtonImage()

Background (ContentBackground)

// Remote image (portrait / landscape)
backgroundImageRemote(
    portraitUrl = "https://cdn.example.com/bg_v.jpg",
    landscapeUrl = "https://cdn.example.com/bg_h.jpg"
)

// Transparent background (removes the default theme background)
backgroundTransparent()

Ad Control

cancel()

Cancels the pending ad display (interrupts the delay if it is still running).

StreamLayerAd.cancel()

hide()

Hides the active overlay. Does nothing if no overlay is visible.

StreamLayerAd.hide()

ReplayService — ads in VOD/replay

ReplayService synchronizes ad promotion display with the video stream's playback position. Used for replay/VOD scenarios.

StreamLayerAd.replay {
    startObserving()  // start tracking the player position
}

// On content end or content change
StreamLayerAd.replay {
    stopObserving()
}

Internal behavior:

  • Polls EventSessionProvider every second for the current stream position
  • Fetches the promotion queue from the server with pagination (100 items per request)
  • Displays a promotion when the current time matches activationTimestamp within ±750 ms
  • Automatically handles forward/backward seeks: invalidates the queue and re-fetches
  • Detects stream pause (if time does not advance for >5 s) and resume

startObserving() requires the SDK to be initialized — must be called inside StreamLayerAd.replay {}.


Handling the Result

All suspend functions return Result<Unit>:

lifecycleScope.launch {
    val result = StreamLayerAd.standard21 {
        titleText = "Promo"
        contentImage("https://cdn.example.com/ad.jpg")
    }
    result.onSuccess {
        Log.d("Ad", "Ad started")
    }.onFailure { error ->
        Log.e("Ad", "Error: ${error.message}")
        // Possible causes: SDK not initialized, VAST URL is empty,
        // invalid configuration, no active stream session
    }
}

Typical Usage Scenario

class PlayerViewModel : ViewModel() {

    // Called when a replay stream starts
    fun onReplayStarted() {
        StreamLayerAd.replay { startObserving() }
    }

    // Called when replay stops
    fun onReplayStopped() {
        StreamLayerAd.replay { stopObserving() }
    }

    // Called on live stream pause — show pause ad
    fun onPlayerPaused() {
        viewModelScope.launch {
            StreamLayerAd.googlePal {
                showPrefetchedAd()
            }
        }
    }

    // Called on stream resume
    fun onPlayerResumed() {
        StreamLayerAd.hide()
    }

    // Set up Google PAL prefetching (call during session initialization)
    fun setupPauseAd(vastUrl: String) {
        viewModelScope.launch {
            StreamLayerAd.googlePal {
                contentVastUrl(vastUrl)
                setupPrefetch() // default 60-minute refresh interval
                viewSideBar()
                resumeButtonText()
            }
        }
    }
}

Interface Support Matrix

Interfacestandard11standard21fullScreengooglePal
ContentHeader
ContentText
ContentImage
ContentVideo
ContentLBar
ContentBackground
ContentButton
ContentResumeButton
ViewMode (Overlay/SideBar/LBar)
FullViewMode (FullScreen)
viewPictureNPicture/SideBySide
contentVastUrl
setupPrefetch/showPrefetched
webView { }
Settings (delay/backPressed)