Server Side Ad Insertion using Brightcove
The fl-ads-brightcove library enables the playback of Brightcove-curated streams with advertisements, providing Server Side Ad Insertion (SSAI) capability for VOD content.
Specifications
- Server-side ads insertion (SSAI) provides a combined video stream of ads and content (ads stitching), resulting in a seamless viewing experience.
- Support for various ad formats, including standard in-stream ads and skippable ads.
- Multiple ad placements: pre-roll, mid-roll, and post-roll ads.
- Thumbnail preview support for enhanced user experience.
- Integration with Brightcove Data Collection API for analytics and reporting.
Usage
Create Content Player
First, create a content player using the PlayerBuilder. This player will handle the main video content.
const playbackOptions = {
autoPlayOnLoad: true,
};
const player = createPlayerBuilder()
.mediaElement(videoElement)
.mediaUrl(assetDetail.contentUrl)
.drmLicenseUrl(assetDetail.licenseUrl)
.mediaType(mediaType)
.certificate(certificate)
.playbackOptions(playbackOptions)
.webVTTThumbnailPreview(assetDetail.thumbnailUrl)
.logger(configuration.getLogger())
.build();
Configure Ad Playback Policies
Define the playback policies for ad handling. These policies control how the player behaves during different playback scenarios.
const playbackPolicies = {
fastForwardMode: PlaybackFastForwardMode.TRICK_FW_PLAY_ALL,
rewindMode: PlaybackRewindMode.TRICK_RW_PLAY_ALL,
autoSeekMode: PlaybackAutoSeekMode.AUTO_SEEK_PLAY_ALL,
repeatMode: PlaybackRepeatedMode.REPEAT_ALWAYS_PLAY,
interruptMode: PlaybackInterruptedMode.INTERRUPT_RESUME,
};
const adPlaybackPolicy = playbackPolicies;
Get Cuepoint Data
Retrieve the ad cuepoint data from the VMAP URL. This data contains information about when and where ads should be played.
const promos = await DefaultBrightcoveManager.getCuepointData(
assetDetail.vmapUrl
);
Create Brightcove Ads Player
Create the Brightcove ads player by combining the content player with ad configuration.
const brightcovePlayer =
await DefaultBrightcoveManager.createBrightcoveAdsPlayer(
player,
configuration.getLogger(),
promos,
adPlaybackPolicy
);
This player can be used like a conventional player from the FLPlayer library for playback.
Thumbnail Preview
The Brightcove ads player supports thumbnail previews for enhanced navigation. You can retrieve thumbnail sprites for a specific playhead position.
// Get thumbnail for a specific position (in seconds)
const response = await brightcovePlayer.getThumbnail(position);
// Access the sprite URL
const spriteUrl = response.url[0];
Listening to Ad Events
The Brightcove ads player can subscribe to ad events to track the state of ad playback and implement custom UIs. The following ad events are available:
| Event Name | Description |
|---|---|
| adbreakstart | Called when an ad break starts |
| adbreakend | Called when an ad break ends |
| adstart | Called when playback of an advert starts |
| adend | Called when playback of an advert ends |
| adcuepoints | Called when cue points are available |
| adprogressupdate | Called when an advert is playing |
| aderror | Called when an error occurs during ad playback |
brightcovePlayer.subscribe('adbreakstart', (adBreakInfo) => {
console.log('Ad break started', adBreakInfo);
// Update the player controls
});
brightcovePlayer.subscribe('adstart', (adInfo) => {
console.log('Ad started', adInfo);
// Display ad information
});
brightcovePlayer.subscribe('adprogressupdate', (adInfo, progress) => {
console.log('Ad progress', progress);
// Update ad countdown timer
});
brightcovePlayer.subscribe('adend', (adInfo) => {
console.log('Ad ended', adInfo);
});
brightcovePlayer.subscribe('adbreakend', (adBreakInfo) => {
console.log('Ad break ended', adBreakInfo);
});
brightcovePlayer.subscribe('aderror', (error) => {
console.error('Ad error', error);
// Handle ad playback errors
});
Ad Metadata
AdBreakInfo
Represents an ad break object.
| Property | Type | Description |
|---|---|---|
| adBreakID | string | Unique id of the ad break |
| contentTimePosition | AdContentTimePosition | The position of the ad break, can be one of preroll, midroll or postroll |
| adBreakStartTimeOffsetMs | number | The start position in milliseconds |
| remainingTimeMs | number | The time remaining in the ad break from the playhead provided, in milliseconds |
| durationMs | number | The duration of the ad break, in milliseconds |
| totalAds | number | Total number of adverts in the ad break |
| adBreakIndex | number | The index of the current ad break |
AdInfo
Represents an advert object.
| Property | Type | Description |
|---|---|---|
| adID | string | The identifier of the advert |
| sequence | number | The sequence of the advert |
| adStartTimeOffsetMs | number | The start playhead position of the advert in milliseconds |
| durationMs | number | The duration of the advert in milliseconds |
| remainingTimeMs | number | Returns the natural playback time remaining for the advert in milliseconds |
| isSkippable | boolean | Indicates if the ad is skippable |
| skipOffsetMs | number | The value of skip offset for the advert, in milliseconds. If the VAST skip offset is not defined then this method returns -1, signifying that the advert cannot be skipped. |
| isFiller | boolean | Whether this advert represents filler content |
| adBreakInfo | AdBreakInfo | The ad break in which the advert belongs in |
| adVastProperties | AdVastProperties | Represents VAST properties of this advert |
AdVastProperties
Represents VAST properties object.
| Property | Type | Description |
|---|---|---|
| adSystem | string | The source ad server of the advert |
| adTitle | string | The common name of the advert |
| adServingId | string | An identifier used to compare impression-level data across systems |
| adId | string | The Ad identifier of the creative |
| creativeId | string | The identifier of the creative |
| category | string | Category of the advert content |
| description | string | The longer description of the advert |
| advertiser | string | Advertiser name |
| pricing | string | Pricing element of the advert |
| survey | string | A URI to any resource file having to do with collecting survey data |
| expires | string | Number of seconds in which the ad is valid for execution |
Brightcove Data Collection API
The fl-ads-brightcove package supports analytics reporting to Brightcove's Data Collection API v2, enabling tracking of playback events, user engagement, and optional QoE (Quality of Experience) metrics.
Configuration Options
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| accountId | number | Yes | - | Your Brightcove Video Cloud account ID |
| videoId | string | Yes | - | The Video Cloud video ID being tracked |
| videoName | string | No | - | Human-readable name of the video for analytics reports |
| sessionId | string | No | Auto-generated UUID v4 | Custom session identifier. Must be globally unique to prevent data collisions |
| engagementEventInterval | number | No | 10000 | Interval in milliseconds between video_engagement events (range: 5000-30000) |
| includeQoEMetrics | boolean | No | false | Enable optional QoE metrics in engagement events. Warning: May impact performance on low-end devices (LG Smart TVs, Tizen, Vizio) |
| userId | string | No | IP + User-Agent hash | Unique user identifier. Should be hashed with SHA-256 for privacy |
| deviceType | string | No | Auto-detected | Device type override. Values: 'mobile', 'tablet', 'tv', 'desktop', 'other' |
| deviceOs | string | No | Auto-detected | Operating system override. Values: 'android', 'ios', 'linux', 'mac', 'windows', 'tv', 'tvos', 'roku', 'tizen' |
| deviceOsVersion | string | No | Auto-detected | OS version (e.g., '14.5', '11') |
| deviceManufacturer | string | No | - | Device manufacturer (e.g., 'Apple', 'Samsung', 'Sony') |
| browserType | string | No | Auto-detected | Browser type (e.g., 'chrome', 'firefox', 'safari') |
| country | string | No | Auto-detected from IP | ISO-3166 alpha-2 country code (e.g., 'US', 'GB', 'DE') |
| countryName | string | No | Auto-detected | Human-readable country name (e.g., 'United States') |
| region | string | No | Auto-detected from IP | ISO-3166 alpha-2 region code (e.g., 'CA' for California, 'NY' for New York) |
| regionName | string | No | Auto-detected | Human-readable region name (e.g., 'California', 'New York') |
| city | string | No | Auto-detected from IP | City name |
| dma | string | No | Auto-detected from IP | Designated Market Area code for US locations |
| destination | string | No | document.location.href | Current page URL where the video is being played |
| source | string | No | document.referrer | Referring page URL |
| playerId | string | No | - | Custom identifier for the player instance |
| playerName | string | No | - | Human-readable name for the player |
| application | string | No | - | Custom application identifier |
| debugLogging | boolean | No | false | Enable debug logging for troubleshooting |
Example Configuration
const dataCollectionConfig = {
// Required
accountId: 123456,
videoId: 'video_abc123',
// Optional - Session tracking
sessionId: 'custom-session-uuid',
engagementEventInterval: 10000,
// Optional - QoE metrics (disabled by default for performance)
includeQoEMetrics: false,
// Optional - User identification
userId: 'hashed-user-id-sha256',
// Optional - Device information (auto-detected if not provided)
deviceType: 'tv',
deviceOs: 'tizen',
deviceOsVersion: '6.0',
deviceManufacturer: 'Samsung',
// Optional - Geographic data (auto-detected from IP if not provided)
country: 'US',
region: 'NY',
city: 'New York',
dma: '501',
// Optional - Player identification
playerId: 'my-custom-player',
playerName: 'Living Room TV',
application: 'my-tv-app',
// Optional - Debugging
debugLogging: false,
};
const brightcovePlayer =
await DefaultBrightcoveManager.createBrightcoveAdsPlayer(
player,
configuration.getLogger(),
promos,
adPlaybackPolicy,
dataCollectionConfig // Pass the config here
);
Tracked Events
The data collection feature automatically tracks the following mandatory events to Brightcove's metrics.brightcove.com endpoint:
| Event Name | Description |
|---|---|
| player_load | Sent when player is initialized |
| video_impression | Sent when video metadata is loaded |
| play_request | Sent when playback is requested |
| video_view | Sent when video playback starts (after pre-roll ads) |
| video_engagement | Sent periodically during playback (interval configurable via engagementEventInterval, default: 10000ms / 10 seconds) |
| ad_mode_begin | Sent when an ad break starts |
| ad_mode_complete | Sent when an ad break ends |
| error | Sent when playback errors occur |
QoE Metrics (Optional)
When includeQoEMetrics: true, the following optional quality metrics are included in video_engagement events:
| Metric | Description |
|---|---|
| rendition_url | URL of the current video rendition |
| rendition_indicated_bps | Bitrate of the current rendition |
| rendition_mime_type | MIME type of the rendition |
| rendition_height | Height of the video rendition in pixels |
| rendition_width | Width of the video rendition in pixels |
| measured_bps | Measured bandwidth (from playbackStatistics.estimatedBandwidth) |
| dropped_frames | Number of dropped frames (from playbackStatistics.droppedFrames) |
| player_width | Player width in pixels |
| player_height | Player height in pixels |
QoE metrics are disabled by default to optimize performance on low-end devices. Enable only if you need detailed quality analytics.
Session Management
- Session ID is automatically generated using UUID v4
- Optionally override with a custom sessionId in the config
- Session ID is consistent across all events in a tracking session
Performance Considerations
- Minimal mode (default): Only sends mandatory events with required parameters
- QoE mode: Subscribes to
trackschangedevents and extracts detailed metrics - For low-end devices (Smart TVs), keep
includeQoEMetrics: false