@bluebillywig/react-native-bb-player
v8.61.0
Published
Blue Billywig Native Video Player for React Native - iOS AVPlayer and Android ExoPlayer integration
Readme
react-native-bb-player
Native video player for React Native - powered by Blue Billywig's iOS and Android SDKs.
Overview
react-native-bb-player provides a production-ready, native video player component for React Native. It wraps Blue Billywig's native iOS and Android player SDKs, giving you:
- True native playback - iOS AVPlayer and Android ExoPlayer (no WebView)
- Full-featured player - Ads, analytics, Content Protection
- Type-safe API - Full TypeScript support with comprehensive types
- Production ready - Built on Blue Billywig's battle-tested native SDKs
- Easy integration - Simple component-based API with imperative ref methods
Compatibility
| Platform | Requirement | Player Engine | |----------|-------------|---------------| | iOS | 12.0+ | AVPlayer | | Android | API 21+ (5.0+) | ExoPlayer | | React Native | 0.73+ | Old & New Architecture (TurboModules) | | Expo | SDK 51+ | With config plugin (optional) |
Installation
npm install @bluebillywig/react-native-bb-player
# or
yarn add @bluebillywig/react-native-bb-playerBare React Native
iOS Setup
cd ios && pod install && cd ..Disabling the Bluetooth permission (Chromecast)
By default the player links the full Google Cast SDK, which discovers nearby
devices over Bluetooth and therefore requires an
NSBluetoothAlwaysUsageDescription entry and shows a Bluetooth permission
prompt. If you don't need Bluetooth-based device discovery, opt into the
Bluetooth-free Cast build — casting still works over the local network, and the
Bluetooth requirement (and its prompt) is dropped.
Set the flag in your Podfile (before use_native_modules!) so it's applied
on every install:
ENV['BB_PLAYER_CAST'] ||= 'nobluetooth'For a one-off install you can also set it from the shell:
BB_PLAYER_CAST=nobluetooth pod installWarning: the shell form does not persist. The next plain
pod install(a teammate, CI) silently reverts to the full Bluetooth Cast SDK — and the permission prompt returns. Use thePodfileform for anything beyond a local experiment.
With nobluetooth you can remove NSBluetoothAlwaysUsageDescription from your
Info.plist. The default (bluetooth) is unchanged for existing apps.
Android Setup
Autolinking handles module registration. As of 8.49.0, the native SDK's transitive dependencies (Google IMA SDK, AndroidX media3) require core library desugaring to be enabled in your app. Merge the following into the existing android { ... } block in android/app/build.gradle (do not add a second android block):
android {
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
}Rebuild Your App
# iOS
npx react-native run-ios
# Android
npx react-native run-androidExpo (Development Build)
Note: This SDK requires native code and cannot run in Expo Go. You must use a development build.
npx expo install @bluebillywig/react-native-bb-playerAdd the config plugin to your app.json:
{
"expo": {
"plugins": [
"@bluebillywig/react-native-bb-player"
]
}
}Then build your development app:
npx expo prebuild
npx expo run:ios
# or
npx expo run:androidSee the Expo Setup Guide for detailed configuration options.
Guides
- Expo Setup Guide - Expo configuration and prebuild
- Fullscreen & Modal Player Guide - Fullscreen, landscape, and modal-style presentation
- Advertising Guide - Ad integration and VAST/VPAID
- Analytics Guide - Analytics integration and custom statistics
- Shorts Guide - Vertical video player (TikTok-style experience)
- Outstream Guide - Outstream advertising with collapse/expand
- Deep Linking Guide - Open video content via URLs
Quick Start
Here's the simplest way to get started:
import React, { useRef } from 'react';
import { View, StyleSheet } from 'react-native';
import { BBPlayerView, type BBPlayerViewMethods } from '@bluebillywig/react-native-bb-player';
export default function App() {
const playerRef = useRef<BBPlayerViewMethods>(null);
return (
<View style={styles.container}>
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
options={{
autoPlay: true,
allowCollapseExpand: true,
}}
onDidTriggerPlay={() => console.log('Playing')}
onDidTriggerPause={() => console.log('Paused')}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#000',
},
});Usage Examples
Basic Video Player
Minimal setup to play a video:
import { BBPlayerView } from '@bluebillywig/react-native-bb-player';
export function BasicPlayer() {
return (
<BBPlayerView
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
options={{ autoPlay: false }}
style={{ flex: 1 }}
/>
);
}With Player Controls
Control playback programmatically:
import React, { useRef } from 'react';
import { View, Button } from 'react-native';
import { BBPlayerView, type BBPlayerViewMethods } from '@bluebillywig/react-native-bb-player';
export function ControlledPlayer() {
const playerRef = useRef<BBPlayerViewMethods>(null);
const handlePlay = () => {
playerRef.current?.play();
};
const handlePause = () => {
playerRef.current?.pause();
};
const handleSeek = () => {
playerRef.current?.seek(30); // Seek to 30 seconds
};
return (
<View style={{ flex: 1 }}>
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
style={{ flex: 1 }}
/>
<View style={{ flexDirection: 'row', padding: 10 }}>
<Button title="Play" onPress={handlePlay} />
<Button title="Pause" onPress={handlePause} />
<Button title="Seek to 30s" onPress={handleSeek} />
</View>
</View>
);
}With Event Listeners
Listen to player events:
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import { BBPlayerView, type State, type Phase } from '@bluebillywig/react-native-bb-player';
export function EventListenerExample() {
const [playerState, setPlayerState] = useState<State>('IDLE');
const [playerPhase, setPlayerPhase] = useState<Phase>('INIT');
const [duration, setDuration] = useState(0);
return (
<View style={{ flex: 1 }}>
<BBPlayerView
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
options={{ autoPlay: true }}
style={{ flex: 1 }}
onDidTriggerStateChange={(state) => setPlayerState(state)}
onDidTriggerPhaseChange={(phase) => setPlayerPhase(phase)}
onDidTriggerDurationChange={(dur) => setDuration(dur)}
onDidTriggerPlay={() => console.log('Playback started')}
onDidTriggerPause={() => console.log('Playback paused')}
onDidTriggerEnded={() => console.log('Playback ended')}
/>
<View style={{ padding: 20, backgroundColor: '#f0f0f0' }}>
<Text>State: {playerState}</Text>
<Text>Phase: {playerPhase}</Text>
<Text>Duration: {duration.toFixed(1)}s</Text>
</View>
</View>
);
}Dynamic Content Loading
Load different content without recreating the player:
import React, { useRef } from 'react';
import { View, Button } from 'react-native';
import { BBPlayerView, type BBPlayerViewMethods } from '@bluebillywig/react-native-bb-player';
export function DynamicLoading() {
const playerRef = useRef<BBPlayerViewMethods>(null);
return (
<View style={{ flex: 1 }}>
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
style={{ flex: 1 }}
/>
<View style={{ padding: 10 }}>
{/* Primary API - loadClip with options */}
<Button
title="Load Clip 123"
onPress={() => playerRef.current?.loadClip('123', { autoPlay: true })}
/>
<Button
title="Load with Playout"
onPress={() => playerRef.current?.loadClip('456', { playout: 'default', autoPlay: true })}
/>
{/* Legacy API - still supported */}
<Button
title="Load ClipList"
onPress={() => playerRef.current?.loadWithClipListId('789', 'user', true)}
/>
</View>
</View>
);
}Loading with Playlist Context
When loading clips within a playlist, pass context to enable "next up" navigation and proper playlist handling:
import React, { useRef } from 'react';
import { View, Button } from 'react-native';
import { BBPlayerView, type BBPlayerViewMethods, type LoadContext } from '@bluebillywig/react-native-bb-player';
export function PlaylistPlayer() {
const playerRef = useRef<BBPlayerViewMethods>(null);
const playlistId = '12345';
// Load a clip from a playlist with context for "next up" navigation
const loadClipFromPlaylist = (clipId: string) => {
playerRef.current?.loadClip(clipId, {
autoPlay: true,
playout: 'default',
context: {
contextEntityType: 'MediaClipList',
contextEntityId: playlistId,
contextCollectionType: 'MediaClipList',
contextCollectionId: playlistId,
},
});
};
return (
<View style={{ flex: 1 }}>
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
style={{ flex: 1 }}
/>
<View style={{ flexDirection: 'row', padding: 10 }}>
<Button title="Load Video 1" onPress={() => loadClipFromPlaylist('clip1')} />
<Button title="Load Video 2" onPress={() => loadClipFromPlaylist('clip2')} />
<Button title="Load Video 3" onPress={() => loadClipFromPlaylist('clip3')} />
</View>
</View>
);
}The context enables:
- Next Up List: Shows upcoming videos from the playlist
- Playlist Navigation: Previous/next buttons work correctly within the playlist
- Proper Analytics: Analytics correctly attribute views to the playlist context
Fullscreen Player
Launch player in fullscreen mode:
import React, { useRef, useEffect } from 'react';
import { BBPlayerView, type BBPlayerViewMethods } from '@bluebillywig/react-native-bb-player';
export function FullscreenPlayer() {
const playerRef = useRef<BBPlayerViewMethods>(null);
return (
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
options={{ autoPlay: true }}
style={{ flex: 1 }}
onDidTriggerApiReady={() => {
// Enter fullscreen landscape once the player is ready
playerRef.current?.enterFullscreenLandscape();
}}
onDidTriggerRetractFullscreen={() => {
console.log('User exited fullscreen');
}}
/>
);
}See the Fullscreen & Modal Player Guide for advanced patterns including modal-style presentation and handling orientation.
Chromecast Support
Open the Google Cast device picker to cast video to Chromecast devices:
import React, { useRef } from 'react';
import { View, Button } from 'react-native';
import { BBPlayerView, type BBPlayerViewMethods } from '@bluebillywig/react-native-bb-player';
export function ChromecastPlayer() {
const playerRef = useRef<BBPlayerViewMethods>(null);
const handleCast = () => {
playerRef.current?.showCastPicker();
};
return (
<View style={{ flex: 1 }}>
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
style={{ flex: 1 }}
/>
<Button title="Cast to Device" onPress={handleCast} />
</View>
);
}Note: Chromecast functionality is available on both iOS and Android platforms.
Continue Watching
Opt in per player with the continueWatching prop. The native SDK then persists the playhead per clip on the device and auto-seeks to it the next time the same clip loads:
<BBPlayerView
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
continueWatching
style={{ flex: 1 }}
/>To render "% watched" badges in a carousel without mounting a player, read the stored position with getLastKnownPosition:
import { getLastKnownPosition } from '@bluebillywig/react-native-bb-player';
const seconds = await getLastKnownPosition('4701337'); // number | null
const watched = seconds != null && clip.length > 0 ? Math.round((seconds / clip.length) * 100) : 0;- Resolves whole seconds — both native SDKs truncate the playhead to an integer before storing it — or
nullwhen the clip has no stored progress. - Rejects on a genuine failure: an empty clip id (
TypeError), or an SDK storage error on Android (E_LAST_KNOWN_POSITION). Wrap the call intry/catchif you want to log those. - The two SDKs currently differ on finished clips: iOS resolves
nullonce a clip has been watched to the end (until it is played again), Android keeps resolving the last offset. This will be aligned in a later SDK release. - Requires native SDK 8.56.0 or later on both platforms (the vendored default).
Example App
The included example app (example/) demonstrates all SDK features. See the Example App docs for TestFlight (iOS) and APK (Android) download instructions.
Screens
| Screen | Description | |--------|-------------| | Simple Player | Minimal player for performance testing | | API Reference | Interactive demo of all player methods: play, pause, seek, volume, fullscreen | | Shorts | Vertical video with swipe navigation, supports full and shelf display modes | | Outstream Ads | Standalone ad player with collapse/expand for article placements | | Modal Player | Native full-screen modal overlay with swipe-to-close (iOS) |
Running Locally
# Install dependencies
npm ci && cd example && npm ci
# iOS
cd ios && pod install && cd ..
npx react-native run-ios
# Android
npx react-native run-androidAPI Reference
Component Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| jsonUrl | string | Yes | JSON embed URL |
| playerId | string | No | Unique identifier for multi-player scenarios |
| jwt | string | No | JWT token for authenticated access |
| continueWatching | boolean | No | Opt into the SDK's Continue Watching feature — playhead is persisted per clip and the player auto-seeks to the stored position on the next load of the same clip. Default off; set true for long-form detail screens. Forwarded into options.continueWatching so consumers using the raw options dict can opt in via that key. |
| options | Record<string, unknown> | No | Player configuration options |
| style | ViewStyle | No | React Native style object |
| Event props | See below | No | Event callback handlers |
Methods (via ref)
// Playback Control
play(): void
pause(): void
seek(position: number): void
seekRelative(offsetSeconds: number): void
// Volume Control
setVolume(volume: number): void
setMuted(muted: boolean): void
// Layout Control
collapse(): void
expand(): void
enterFullscreen(): void
enterFullscreenLandscape(): void
exitFullscreen(): void
// Chromecast
showCastPicker(): void
// Load Content (Primary API)
loadClip(clipId: string, options?: LoadClipOptions): void
// Load Content (Legacy - all support optional context parameter)
loadWithClipId(clipId: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext): void
loadWithClipListId(clipListId: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext): void
loadWithProjectId(projectId: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext): void
loadWithClipJson(clipJson: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext): void
loadWithClipListJson(clipListJson: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext): void
loadWithProjectJson(projectJson: string, initiator?: string, autoPlay?: boolean, seekTo?: number, context?: LoadContext): void
loadWithJsonUrl(jsonUrl: string, autoPlay?: boolean, context?: LoadContext): void
// Async Getters (Primary API)
getPlayerState(): Promise<BBPlayerState | null> // Returns complete player state
// Async Getters (Individual)
getDuration(): Promise<number | null>
getMuted(): Promise<boolean | null>
getVolume(): Promise<number | null>
getPhase(): Promise<string | null>
getState(): Promise<string | null>
getMode(): Promise<string | null>
getClipData(): Promise<{ id?: string; title?: string; description?: string; length?: number } | null>
getProjectData(): Promise<{ id?: string; name?: string } | null>
getPlayoutData(): Promise<{ name?: string } | null>
// Cleanup
destroy(): void
autoPlayNextCancel(): voidModule-level Functions
import { getLastKnownPosition, addCastSessionListener, BBModalPlayer } from '@bluebillywig/react-native-bb-player';
// Continue Watching — stored playhead in whole seconds, or null when there is no record.
// Rejects on an empty clip id or a native lookup failure. See "Continue Watching" above.
getLastKnownPosition(clipId: string): Promise<number | null>Events
// Setup & Lifecycle
onDidSetupWithJsonUrl?: (url: string) => void
onDidTriggerApiReady?: () => void
onDidFailWithError?: (error: string) => void
// Playback
onDidTriggerPlay?: () => void
onDidTriggerPause?: () => void
onDidTriggerPlaying?: () => void
onDidTriggerEnded?: () => void
onDidTriggerCanPlay?: () => void
onDidTriggerSeeking?: () => void
onDidTriggerSeeked?: (position: number) => void
onDidTriggerStall?: () => void
onDidTriggerDurationChange?: (duration: number) => void
onDidTriggerVolumeChange?: (volume: number) => void
// State Changes
onDidTriggerStateChange?: (state: State) => void
onDidTriggerPhaseChange?: (phase: Phase) => void
onDidTriggerModeChange?: (mode: string) => void
// Media Loading
onDidTriggerMediaClipLoaded?: (clip: MediaClip) => void
onDidTriggerMediaClipFailed?: () => void
onDidTriggerProjectLoaded?: (project: Project) => void
// View Events
onDidTriggerViewStarted?: () => void
onDidTriggerViewFinished?: () => void
// Fullscreen
onDidTriggerFullscreen?: () => void
onDidTriggerRetractFullscreen?: () => void
// Layout
onDidRequestCollapse?: () => void
onDidRequestExpand?: () => void
onDidRequestOpenUrl?: (url: string) => void
// Auto-Pause
onDidTriggerAutoPause?: (why: string) => void
onDidTriggerAutoPausePlay?: (why: string) => void
// Ads
onDidTriggerAdLoadStart?: () => void
onDidTriggerAdLoaded?: () => void
onDidTriggerAdStarted?: () => void
onDidTriggerAdFinished?: () => void
onDidTriggerAdNotFound?: () => void
onDidTriggerAdError?: (error: string) => void
onDidTriggerAdQuartile1?: () => void
onDidTriggerAdQuartile2?: () => void
onDidTriggerAdQuartile3?: () => void
onDidTriggerAllAdsCompleted?: () => void
// Outstream companion became the exit screen (payload = matched slot size; no URL — IMA owns rendering/click).
// iOS only, requires BBNativePlayerKit 8.56.0+; this package vendors 8.56.0 (see native-sdk-versions.json).
// Not implemented on Android — the RN bridge for this event has not been written (ADO #19723).
onDidShowCompanionAd?: (companion: { width: number; height: number }) => void
// Custom Statistics (for analytics integration)
onDidTriggerCustomStatistics?: (stats: CustomStatistics) => voidNote: See the Analytics Guide for detailed analytics integration examples.
TypeScript Types
// Player state enum
type State = "IDLE" | "LOADING" | "PLAYING" | "PAUSED" | "ERROR";
type Phase = "INIT" | "PRE" | "MAIN" | "POST" | "EXIT";
// Options for loadClip()
type LoadClipOptions = {
playout?: string; // Playout name/ID
autoPlay?: boolean; // Auto-play after loading
seekTo?: number; // Seek to position (seconds)
initiator?: string; // Analytics initiator
context?: LoadContext; // Playlist/collection context
};
// Context for playlist/collection navigation
type LoadContext = {
contextEntityType?: 'MediaClipList'; // Type of the containing entity
contextEntityId?: string; // Playlist ID for "next up" list
contextCollectionType?: 'MediaClipList'; // Type of the collection
contextCollectionId?: string; // Collection ID if playing within a collection
};
// Complete player state object (returned by getPlayerState())
type BBPlayerState = {
state: State;
phase: Phase;
mode: string | null;
duration: number;
muted: boolean;
volume: number;
clip: { id?: string; title?: string; description?: string; length?: number } | null;
project: { id?: string; name?: string } | null;
playout: { name?: string } | null;
};
// Event payload types (for typed event handling)
type BBPlayerEventPayloads = {
play: void;
pause: void;
stateChange: { state: State };
phaseChange: { phase: Phase };
// ... and more
};Getting Complete Player State
Use getPlayerState() to fetch all player state at once:
const handleGetState = async () => {
const state = await playerRef.current?.getPlayerState();
if (state) {
console.log(`Playing: ${state.state === 'PLAYING'}`);
console.log(`Duration: ${state.duration}`);
console.log(`Clip: ${state.clip?.title}`);
console.log(`Volume: ${state.volume}, Muted: ${state.muted}`);
}
};Overriding Native SDK Versions
Current Versions
- iOS:
8.56.0vendored;>= 8.56.0when resolved from CocoaPods (Blue Billywig Native Player Kit) - Android:
8.56.0(Blue Billywig Native Player SDK)
Override iOS (in Podfile)
pod 'BlueBillywigNativePlayerKit-iOS', '8.56.0'Override Android (in android/app/build.gradle)
configurations.all {
resolutionStrategy {
force 'com.bluebillywig.bbnativeplayersdk:bbnativeplayersdk:8.42.0'
}
}Troubleshooting
"Module not found"
- Ensure the package is installed
- Run
cd ios && pod install - Rebuild the app completely
Black Screen on Player
- Check the JSON URL is correct and accessible
- Verify internet connectivity
- Add error handling to debug:
<BBPlayerView
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
onDidFailWithError={(error) => console.error('Player error:', error)}
onDidSetupWithJsonUrl={(url) => console.log('Player setup complete:', url)}
/>Player Not Responding to Method Calls
Ensure the player is ready before calling methods:
const [isReady, setIsReady] = useState(false);
<BBPlayerView
ref={playerRef}
onDidTriggerCanPlay={() => setIsReady(true)}
/>
// Then call methods
if (isReady) {
playerRef.current?.play();
}iOS Build Fails
- Run
cd ios && pod deintegrate && pod install - Clean build folder in Xcode
Android Build Fails
- Run
cd android && ./gradlew clean - Ensure JDK 17+ is installed
Safe Area Handling (iOS + Android)
React Native's built-in SafeAreaView doesn't work consistently across platforms. For reliable safe area handling on both iOS and Android, use react-native-safe-area-context:
npm install react-native-safe-area-contextSetup:
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
function App() {
return (
<SafeAreaProvider>
<MyScreen />
</SafeAreaProvider>
);
}In your screens:
import { SafeAreaView } from 'react-native-safe-area-context';
function PlayerScreen() {
return (
<SafeAreaView style={{ flex: 1 }}>
<BBPlayerView jsonUrl="..." style={{ flex: 1 }} />
</SafeAreaView>
);
}For more control with insets:
import { useSafeAreaInsets } from 'react-native-safe-area-context';
function CustomScreen() {
const insets = useSafeAreaInsets();
return (
<View style={{ flex: 1, paddingTop: insets.top, paddingBottom: insets.bottom }}>
<BBPlayerView jsonUrl="..." style={{ flex: 1 }} />
</View>
);
}New Architecture (Fabric & TurboModules)
This package fully supports React Native's New Architecture, including:
- Fabric - The new rendering system
- TurboModules - The new native module system with synchronous access and lazy loading
Automatic Detection
The package automatically detects which architecture your app uses:
- New Architecture enabled: Uses
TurboModuleRegistryfor optimal performance - Old Architecture: Falls back to
NativeModules(no changes needed)
Enabling New Architecture
React Native 0.76+
New Architecture is enabled by default in React Native 0.76 and later.
React Native 0.73-0.75
Enable in your app's configuration:
Android (android/gradle.properties):
newArchEnabled=trueiOS (ios/Podfile):
ENV['RCT_NEW_ARCH_ENABLED'] = '1'Then rebuild your app:
# iOS
cd ios && pod install && cd ..
npx react-native run-ios
# Android
cd android && ./gradlew clean && cd ..
npx react-native run-androidNo Code Changes Required
Your existing code works with both architectures. The package handles the architecture detection internally:
// This works on both Old and New Architecture
import { BBPlayerView } from '@bluebillywig/react-native-bb-player';
<BBPlayerView
ref={playerRef}
jsonUrl="https://demo.bbvms.com/p/default/c/4701337.json"
onDidTriggerPlay={() => console.log('Playing')}
/>FAQ
Can I use this in production?
Yes! This package wraps Blue Billywig's production-grade native SDKs used by major media companies.
Does this support ads?
Yes, the player includes full ad support (VAST, VPAID, etc.). Configure ads in your Blue Billywig playout configuration.
What video formats are supported?
The player supports formats compatible with:
- iOS: AVPlayer (HLS, MP4, M4V, MOV, etc.)
- Android: ExoPlayer (HLS, DASH, MP4, WebM, etc.)
How do I get a JSON URL?
Contact Blue Billywig to get access to your media content. The JSON URL format is:
https://{your-domain}.bbvms.com/p/{playout}/c/{clipId}.jsonAPI Documentation
Full TypeScript API documentation is available at:
https://bluebillywig.github.io/react-native-bb-player/
The documentation is automatically generated from source code and updated on every release.
Support
Issues
When reporting an issue, please include:
- React Native version
- Platform (iOS/Android)
- Reproduction steps
License
MIT
Built with love by Blue Billywig
