AdsBroadpeak Library
Broadpeak SmartLib integration. The fl-ads-broadpeak library integrates with
Broadpeak to offer Server Side Ad Insertion (SSAI) capability for both VOD and
Live on iOS and Android.
Setup
- Android
- iOS
Adding dependencies to the project
-
Add the Broadpeak repository for SmartLib in root
build.gradle:maven { url 'https://delivery-platform.broadpeak.tv/android/repository/all' } -
Add the following Broadpeak dependency in the application module
build.gradle:implementation "tv.broadpeak.smartlib:smartlib-media3:06.00.02.845a8c7"
Note: Use the Broadpeak and Google PAL library version shipped with the QuickPlay libraries.
Adding dependencies to the project
-
Add the Broadpeak pod source at the top of your
Podfile, before any other source declarations:source 'https://cdn.cocoapods.org/'source 'https://delivery-platform.broadpeak.tv/ios/broadpeak/specs.git' -
Set the environment variable in your
Podfileinside the target block to enable Broadpeak:ENV['USE_BROADPEAK_PLAYER'] = '1' -
Run
pod installafter updating sources.
Known iOS integration issues
The following issue occurs when integrating SmartLib (Broadpeak) on iOS.
Apply the workaround inside the post_install block of your Podfile.
Issue: App Store rejection due to nested framework inside SmartLibOMSDK.framework
Problem:
SmartLibOMSDK.framework ships with a nested Frameworks/ directory
containing OMSDK_Broadpeaktv.framework. Apple does not allow frameworks
nested inside other frameworks in the final app bundle. This causes App Store
submission to be rejected with an error such as:
ITMS-90206: Invalid Bundle. The bundle at '...SmartLibOMSDK.framework' contains disallowed nested bundles.
Workaround:
Add a post_install hook to your Podfile that automatically injects an
archive-only Run Script build phase into your app target. The script removes
the nested Frameworks/ directory from SmartLibOMSDK.framework and re-signs
the modified framework.
post_install do |installer|
# Resolve the fix script from the installed npm package
sdk_root = `node --print "path.dirname(require.resolve('@quickplay/rn-qp-nxg-player/package.json'))"`.strip
script_path = File.join(sdk_root, 'ios', 'Scripts', 'fix_broadpeak_framework_packaging.sh')
script_content = File.read(script_path)
phase_name = 'Fix Broadpeak Framework Packaging'
# Use aggregate_target.user_project (CocoaPods' memoized reference) so our save
# is the final write and cannot be overwritten by CocoaPods' own project save.
seen_projects = {}
installer.aggregate_targets.each do |aggregate_target|
user_project = aggregate_target.user_project
next if user_project.nil? || seen_projects[user_project.path]
seen_projects[user_project.path] = true
user_project.targets.each do |target|
next unless target.name == '<YourAppTarget>'
next if target.build_phases.any? { |p| p.respond_to?(:name) && p.name == phase_name }
phase = target.new_shell_script_build_phase(phase_name)
phase.shell_script = script_content
phase.run_only_for_deployment_postprocessing = '1'
end
user_project.save
end
# ... rest of your post_install block
end
Replace
<YourAppTarget>with your actual Xcode target name. Therun_only_for_deployment_postprocessing = '1'flag ensures the script runs only during archive builds. The script itself also guards against non-archive and non-device builds, so it is safe to run unconditionally.
Create Broadpeak session initialization data
The initializationData is created by passing parameters to
BroadpeakInitializationData.
import {
BroadpeakCDN,
AnalyticsHost,
BroadpeakInitializationData,
} from '@quickplay/rn-qp-nxg-player';
const broadpeakCDN: BroadpeakCDN = {
type: '<cdn type>',
domainHostNames: ['<broadpeak cdn hostname>'], // required when type is 'Custom'
};
const analyticsHostNames: AnalyticsHost = {
type: '<analytics host type>',
hostNames: ['<analytics server url>'], // required when type is 'Custom'
};
const config: BroadpeakInitializationData = {
broadpeakDomainHostNames: broadpeakCDN,
analyticsHostNames: analyticsHostNames,
uuid: '<unique user or account identifier>',
deviceType: '<device type>',
userAgent: '<user agent string>',
gdprPreference: <gdpr preference>, // 1 = GDPR_DELETE | 2 = GDPR_ANONYMIZED | 3 = GDPR_ENCRYPTED | 4 = GDPR_CLEAR
sessionKeepAliveFrequencyMs: <keep alive frequency in ms>,
loggerLevel: <logger level>, // -1 = LOG_OFF | 0 = LOG_BASIC | 1 = LOG_VERBOSE
allowStorage: <allow storage>,
};
| Property | Type | Mandatory | Description |
|---|---|---|---|
| broadpeakDomainHostNames | BroadpeakCDN | Yes | The domainHostNames list used to identify Broadpeak sessions (for example, "cdn.broadpeak.com"). type: 'All' means all sessions use a Broadpeak CDN. type: 'None' means no URLs are on a Broadpeak CDN. type: 'Custom' means only the listed hostnames are Broadpeak CDN. |
| analyticsHostNames | AnalyticsHost | No | Analytics server hostnames (for example, "https://server-host"). type: 'None' disables analytics reporting. |
| uuid | string | No | A unique user or account identifier used by Broadpeak Analytics. |
| deviceType | string | No | Overrides the default device type detected by SmartLib (for example, "phone", "tablet", "tv"). |
| userAgent | string | No | The user agent string used when firing Broadpeak analytics and ad tracking beacons. |
| gdprPreference | BroadpeakGDPRPreference | No | GDPR preference for Broadpeak Analytics. GDPR_DELETE means report is empty. GDPR_ENCRYPTED means decryptable on request. GDPR_ANONYMIZED means no decryption possible. GDPR_CLEAR means no encryption (default). |
| sessionKeepAliveFrequencyMs | number | No | Overrides the default SmartLib keep-alive frequency (default: 5000 ms). Valid range: 5000-10000 ms. |
| loggerLevel | BroadpeakLoggerLevelOrdinal | No | Logger verbosity. LOG_BASIC is basic logging, LOG_VERBOSE is verbose logging, and LOG_OFF disables logging. |
| allowStorage | boolean | No | Whether SmartLib can persist data to local storage (for example, for session continuity). |
Per-session configuration (BroadpeakSessionConfig)
BroadpeakSessionConfig is passed per-playback session inside PlayerConfig
(via broadpeakSessionConfig). It is optional in PlayerConfig, but required
for Broadpeak SSAI playback because initializationUrl is needed to create the
Broadpeak session.
import { BroadpeakSessionConfig } from '@quickplay/rn-qp-nxg-player';
const broadpeakSessionConfig: BroadpeakSessionConfig = {
initializationUrl: '<session initialization url>',
pipSession: <pip session enabled>,
customParams: {
'<key>': '<value>',
},
adParams: {
'<key>': '<value>',
},
};
| Property | Type | Mandatory | Description |
|---|---|---|---|
| initializationUrl | string | Yes | Broadpeak session initialization URL. |
| pipSession | boolean | No | Set to true if the session needs to support Picture-in-Picture. |
| customParams | { [key: string]: string } | No | Custom key-value pairs sent to Broadpeak Analytics. |
| adParams | { [key: string]: string } | No | Custom key-value pairs forwarded to Broadpeak ad requests. |
Initialize Broadpeak SmartLib instance
This must be done once, when the app starts (for example, in your root component or app entry point):
await broadpeakSessionManager.initWithConfig(config);
Check if Broadpeak SmartLib is initialized
const configured: boolean = await broadpeakSessionManager.isConfigured();
Release Broadpeak SmartLib instance
Call this when the app is closing (Android only; not implemented on iOS):
await broadpeakSessionManager.dispose();
Note:
initWithConfig()must be paired withdispose()on Android. On iOS,dispose()is a no-op.
Create ad player
const playerConfig: PlayerConfig = {
contentType: '<content type>',
isSSAIEnabled: true, // mandatory for Broadpeak
ssaiAdProvider: 'broadpeak', // mandatory for Broadpeak
mediaURL: '<content url>',
mediaType: '<media type>', // required for live content
palConfiguration: {
// required when using Broadpeak SSAI with Google PAL
descriptionURL: '<content or page url>',
omidPartnerName: '<omid partner name>',
omidPartnerVersion: '<omid partner version>',
omidVersion: '<omid version>',
playerType: '<player type>',
playerVersion: '<player version>',
ppid: '<publisher provided id>',
videoPlayerHeight: 720,
videoPlayerWidth: 1280,
},
broadpeakSessionConfig: {
initializationUrl: '<session initialization url>',
pipSession: <pip session enabled>,
customParams: { '<key>': '<value>' },
},
};
const broadpeakAdPlayer = await createPlayer(playerConfig);
// Attach player listeners before calling play.
broadpeakAdPlayer.play();
| Property | Type | Mandatory | Description |
|---|---|---|---|
| mediaURL | string | Yes | The playback URL. |
| contentType | ConsumptionTypeValue | Yes | 'VOD' or 'LIVE'. |
| isSSAIEnabled | boolean | Yes | Must be true for SSAI/Broadpeak playback. |
| ssaiAdProvider | ssaiAdProvider | Yes | Must be 'broadpeak'. |
| mediaType | MediaType | Yes | 'HLS' or 'DASH'. |
| broadpeakSessionConfig | BroadpeakSessionConfig | Yes | Per-session Broadpeak config. initializationUrl is required. |
| palConfiguration | PALConfiguration | No | Per-session PAL config. Required when using Broadpeak SSAI with Google PAL. |
| adPlaybackPolicy | AdPlaybackPolicy | No | Defines ad playback policy for VOD content. |
Example integration
The following example shows a complete integration using the Broadpeak APIs:
checking isConfigured(), initializing SmartLib via initWithConfig(),
creating a Broadpeak SSAI player with broadpeakSessionConfig, and releasing
SmartLib via dispose() on teardown.
import {
broadpeakSessionManager,
createPlayer,
BroadpeakCDN,
AnalyticsHost,
BroadpeakInitializationData,
PlayerConfig,
} from '@quickplay/rn-qp-nxg-player';
// 1. Check isConfigured() — returns the isInitialized flag value.
// Only call initWithConfig() when SmartLib is not yet initialized.
const configured = await broadpeakSessionManager.isConfigured();
if (!configured) {
const broadpeakCDN: BroadpeakCDN = {
type: 'Custom',
domainHostNames: ['ucdn.mediaquest.com.ph'],
};
const analyticsHostNames: AnalyticsHost = {
type: 'None',
};
const config: BroadpeakInitializationData = {
broadpeakDomainHostNames: broadpeakCDN,
analyticsHostNames,
uuid: '',
deviceType: '',
userAgent: '',
gdprPreference: 2, // GDPR_ANONYMIZED
sessionKeepAliveFrequencyMs: 5000,
loggerLevel: 0, // LOG_BASIC
allowStorage: true,
};
// 2. initWithConfig() — sets isInitialized to true; isConfigured() returns true after this.
await broadpeakSessionManager.initWithConfig(config);
}
// 3. createPlayer() — requires isInitialized = true (isConfigured() must return true).
const playerConfig: PlayerConfig = {
contentType: 'LIVE',
isSSAIEnabled: true,
ssaiAdProvider: 'broadpeak',
mediaURL:
'https://ucdn.mediaquest.com.ph/bpk-tv/ssai_test/default/index.m3u8',
mediaType: 'HLS',
broadpeakSessionConfig: {
initializationUrl: 'https://example.com/broadpeak/session/init',
pipSession: true,
customParams: { key1: 'value1' },
adParams: { adKey: 'adValue' },
},
};
const player = await createPlayer(playerConfig);
// Add required player listeners before playback.
player.play();
// Optional: when closing the app on Android.
await broadpeakSessionManager.dispose();