Skip to main content

Outstream Advertising

Outstream ads run independently of video content — they're standalone ad players designed for embedding within articles, feeds, or scrollable content.

FeatureOutstreamInstream
Video contentNot requiredRequired
PlacementAnywhereWithin video player
Collapse/ExpandYesNo
Use caseArticle monetizationVideo monetization

URL Format​

# Outstream (note /a/ path)
https://{domain}.bbvms.com/a/{outstreamPlayout}.json

# Regular video (for comparison)
https://{domain}.bbvms.com/p/{playout}/c/{clipId}.json

Pre-built wrapper with automatic collapse/expand animations:

import React, { useRef, useEffect } from 'react';
import { ScrollView, Text, StyleSheet } from 'react-native';
import { BBOutstreamPlayerView, type BBOutstreamViewMethods } from '@bluebillywig/react-native-bb-player';

function ArticleWithAd() {
const outstreamRef = useRef<BBOutstreamViewMethods>(null);

useEffect(() => {
return () => outstreamRef.current?.destroy();
}, []);

return (
<ScrollView style={styles.container}>
<Text style={styles.paragraph}>Article content above the ad...</Text>

<BBOutstreamPlayerView
ref={outstreamRef}
jsonUrl="https://demo.bbvms.com/a/native_sdk_outstream.json"
expandedHeight={250}
style={styles.ad}
onCollapsed={() => console.log('Collapsed')}
onExpanded={() => console.log('Expanded')}
onDidTriggerAdStarted={() => console.log('Ad started')}
/>

<Text style={styles.paragraph}>Article content below the ad...</Text>
</ScrollView>
);
}

Animation Options​

// Smooth timing (default)
<BBOutstreamPlayerView animation={{ type: 'timing', duration: 300 }} />

// Spring with bounce
<BBOutstreamPlayerView animation={{ type: 'spring', damping: 15, stiffness: 100 }} />

// LayoutAnimation
<BBOutstreamPlayerView animation={{ type: 'layout', duration: 250 }} />

// Instant
<BBOutstreamPlayerView animation={{ type: 'none' }} />

Props​

PropTypeDefaultDescription
jsonUrlstringRequiredOutstream ad URL (/a/ endpoint)
expandedHeightnumber200Height when expanded (px)
collapsedHeightnumber0Height when collapsed (px)
animationOutstreamAnimationConfigtiming, 300msAnimation config
onCollapsed() => void—After collapse completes
onExpanded() => void—After expand completes
All BBPlayerView props——All player events supported

Methods​

MethodDescription
isCollapsed()Returns current collapsed state
animateCollapse()Programmatic collapse
animateExpand()Programmatic expand
+ all BBPlayerViewMethodsStandard player controls

Option 2: BBPlayerView (Manual)​

For full control over collapse/expand:

import React, { useRef, useCallback } from 'react';
import { Animated } from 'react-native';
import { BBPlayerView, type BBPlayerViewMethods } from '@bluebillywig/react-native-bb-player';

const EXPANDED = 250;

function OutstreamManual() {
const playerRef = useRef<BBPlayerViewMethods>(null);
const height = useRef(new Animated.Value(EXPANDED)).current;

const collapse = useCallback(() => {
Animated.timing(height, { toValue: 0, duration: 300, useNativeDriver: false }).start();
}, []);

const expand = useCallback(() => {
Animated.timing(height, { toValue: EXPANDED, duration: 300, useNativeDriver: false }).start();
}, []);

return (
<Animated.View style={{ height, overflow: 'hidden', backgroundColor: '#000' }}>
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/a/native_sdk_outstream.json"
options={{ allowCollapseExpand: true }}
style={{ flex: 1 }}
onDidRequestCollapse={collapse}
onDidRequestExpand={expand}
/>
</Animated.View>
);
}

Ad Targeting Parameters​

options={{
allowCollapseExpand: true,
adsystem_buid: 'browser-unique-id',
adsystem_rdid: 'resettable-device-id',
adsystem_idtype: 'idfa', // or 'aaid' for Android
adsystem_is_lat: '0', // '1' if limit ad tracking
adsystem_ppid: 'publisher-id',
}}

Companion Exit Screen​

When the ad's VAST response carries a companion matching one of the player's IMA companion-slot sizes, the native SDK keeps the player open after the ad and shows the companion as the exit screen. onDidShowCompanionAd fires once per ad break at that moment:

<BBOutstreamPlayerView
jsonUrl="https://demo.bbvms.com/a/native_sdk_outstream.json"
onDidShowCompanionAd={({ width, height }) =>
console.log(`Companion shown: ${width}x${height}`)
}
/>

The payload is the matched companion-slot size (not the on-screen rendered size, which is fitted to the player width). There is no image or clickthrough URL in the payload by design: the IMA SDK renders the companion and handles the click.

iOS only — requires BBNativePlayerKit 8.56.0 or newer, which is where the companion feature first ships; this package vendors 8.56.0 (see native-sdk-versions.json in the repo root). Not implemented on Android — the RN bridge for this event has not been written (ADO #19723).

Best Practices​

  1. Place at content breaks — between paragraphs for natural flow
  2. Start muted — autoMute: true for better UX
  3. Appropriate height — typically 200–300px
  4. Always cleanup — destroy() on unmount
  5. Handle errors — hide failed ads gracefully
  6. Track events — monitor ad performance

Troubleshooting​

IssueSolution
Ad not loadingVerify URL uses /a/ path (not /p/)
Collapse/expand brokenSet allowCollapseExpand: true in options
Animation issuesTry different animation type; enable LayoutAnimation on Android
Height not updatingEnsure overflow: 'hidden' on container