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
standard11 — 1:1 bannerAspect 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
standard21 — 2:1 banner with textAspect 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
fullScreen — full-screen adSupports 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:
| Method | Description |
|---|---|
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()(fromFullViewMode) is used with GooglePal, only image mode is available (AdContentType.Image_Only). Forstandard11/standard21,viewFullScreen()switches the overlay toFullBleedmode.
googlePal — Google PAL VAST/WebView ad
googlePal — Google PAL VAST/WebView adsuspend fun googlePal(block: Builder.GooglePal.() -> Unit): Result<Unit>GooglePal-specific methods:
| Method | Description |
|---|---|
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:
| Parameter | Type | Description |
|---|---|---|
host | String | Required. Base URL of the ad server, will be providen for you. |
url | String? | Required. VAST URL, GPT URL (output=ldjh), or GPT slot ID (non-HTTP path) |
brand | String? | Brand name |
product | String? | Product identifier (e.g., tsn). Used for ad unit path building |
content | String? | Content identifier (e.g., cfl-news-and-highlights). Used for ad unit path building |
platform | String? | Platform identifier (e.g., cotv). Used for ad unit path building |
platformtype | String? | Platform type (e.g., androidtv, amazonfire, googletv). Used for ad unit path building |
pagetype | String? | Page type (e.g., playerpage). Used for ad unit path building |
revshare | String? | Revenue share identifier |
npa | Int? | Non-personalized ads flag (1 = non-personalized). When npa=1, permutive targeting keys are stripped |
target | String? | Custom GPT key-value targeting pairs (passed as t= param to the ad host) |
islat | Int? | Limit ad tracking flag (1 = limited) |
width | Int? | Ad unit width |
height | Int? | Ad unit height |
slot | String? | Ad slot identifier |
The SDK automatically appends
rdid(device advertising ID) andidtype=adidto 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 receivesonActionClicked(ActionClicked(Source.BACK_BUTTON))viaSLRAppHost.
View Modes (ViewMode / FullViewMode)
| Method | Type | Description |
|---|---|---|
viewOverlay() | ViewMode | Overlay on top of the video |
viewSideBar() | ViewMode | Side bar (default) |
viewLBar() | ViewMode | L-shaped banner |
viewFullScreen() | FullViewMode | Full screen mode (FullBleed) |
viewPictureNPicture() | FullScreen only | Picture-in-Picture |
viewSideBySide() | FullScreen only | Side-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()
cancel()Cancels the pending ad display (interrupts the delay if it is still running).
StreamLayerAd.cancel()hide()
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
EventSessionProviderevery 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
activationTimestampwithin ±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 insideStreamLayerAd.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
| Interface | standard11 | standard21 | fullScreen | googlePal |
|---|---|---|---|---|
ContentHeader | ✅ | ✅ | ✅ | — |
ContentText | — | ✅ | ✅ | — |
ContentImage | ✅ | ✅ | — | — |
ContentVideo | ✅ | ✅ | ✅ | — |
ContentLBar | ✅ | ✅ | — | — |
ContentBackground | ✅ | ✅ | ✅ | — |
ContentButton | ✅ | ✅ | ✅ | — |
ContentResumeButton | ✅ | ✅ | ✅ | ✅ |
ViewMode (Overlay/SideBar/LBar) | ✅ | ✅ | — | ✅ |
FullViewMode (FullScreen) | ✅ | ✅ | — | ✅ |
viewPictureNPicture/SideBySide | — | — | ✅ | — |
contentVastUrl | — | — | — | ✅ |
setupPrefetch/showPrefetched | — | — | — | ✅ |
webView { } | — | — | — | ✅ |
Settings (delay/backPressed) | ✅ | ✅ | ✅ | ✅ |
Updated 8 days ago
