Advanced topics
How to implement the Brightline SDK for MediaTailor
This implementation provides a seamless integration between MediaTailor's server-side ad insertion, Datazoom's event detection, and BrightLine's interactive overlay capabilities.
Part 1: Event Detection and Triggering Concept
Overview
The implementation uses a two-SDK approach where Datazoom SDK acts as the event detection layer and BrightLine SDK handles the interactive overlay rendering. The flow works as follows:
Datazoom SDK monitors MediaTailor session events and detects when non-linear ads should be displayed
Event Bridge - When a NONLINEAR_AD_START event is detected, it triggers the BrightLine SDK
BrightLine SDK renders the interactive overlay with squeezeback animation
Automatic Cleanup - When NONLINEAR_AD_END is detected, the overlay is closed and video restored
Event Detection Flow
MediaTailor Stream → Datazoom SDK → Event Detection → BrightLine SDK → Overlay Display
↓
NONLINEAR_AD_START
↓
Extract Ad Data & Duration
↓
Trigger BrightLine
↓
Squeezeback Animation
↓
NONLINEAR_AD_END
↓
Close Overlay & Restore
Key Event Types
NONLINEAR_AD_START: Triggered when a non-linear overlay ad should begin
NONLINEAR_AD_END: Triggered when the overlay ad duration expires
Squeezeback Animation Concept
The "squeezeback" effect shrinks the video player to make room for the overlay ad:
Video element is smoothly animated to 60% size
Video is repositioned with CSS transforms
Overlay iframe is positioned behind the video
Animation is reversed when ad ends
Part 2: Code Implementation Examples
1. Datazoom SDK Event Listener Setup
JavaScript
// Initialize Datazoom with MediaTailor session
const context = datazoom.createContext(hlsPlayer, {
adapterOptions: { hlsClass: Hls }
});
context.attachMediaTailorSession(session);
// Set up event listeners for non-linear ads
session.addEventListener(mediatailor.SessionUiEvent.NONLINEAR_AD_START, event => {
handleNonLinearAdStart(event.detail?.nonLinearAdsObject);
videoElement.controls = false; // Hide video controls during ad
});
session.addEventListener(mediatailor.SessionUiEvent.NONLINEAR_AD_END, event => {
handleNonLinearAdEnd(event.detail?.nonLinearAdsObject);
videoElement.controls = true; // Restore video controls
});
2. Non-Linear Ad Start Handler
JavaScript
const handleNonLinearAdStart = async (event) => {
// Extract ad data from the event
const { nonLinearAdList, trackingEvents, duration } = event.adData;
const nonLinearAd = nonLinearAdList[0];
// Create tracking data for analytics
const trackingNodeStr = JSON.stringify({
trackingEvents: {
createView: trackingEvents
.filter(event => event.eventType === 'impression')
.map(event => event.beaconUrls)
.flat()
}
});
// Trigger BrightLine SDK to show overlay
await BrightlineSDKWrapper.openAd(
nonLinearAd.iFrameResource, // Ad content URL
'player', // Video element ID
true, // Enable close button
'channel-name', // Channel identifier
trackingNodeStr, // Tracking data
duration // Ad duration in seconds
);
};
3. BrightLine SDK Wrapper Core Methods
JavaScript
const BrightlineSDKWrapper = {
// Initialize the SDK
init: async () => {
await loadBrightlineScript();
setupEventCallbacks();
},
// Open an overlay ad with squeezeback animation
openAd: async (src, playerId, enableClose, channel, tracking, duration) => {
// Load the overlay content
window.BL.openAd(src, playerId, enableClose, channel, tracking, duration);
// Trigger custom squeezeback animation
setTimeout(() => {
triggerSqueezebackAnimation(playerId, duration);
}, 100);
},
// Close ad and restore video
closeAd: async () => {
await restoreVideoPlayer();
window.BL.closeAd();
}
};
4. Squeezeback Animation Implementation
JavaScript
const triggerSqueezebackAnimation = (playerId, duration) => {
const videoElement = document.getElementById(playerId);
// Store original video state
const originalState = {
width: videoElement.style.width,
height: videoElement.style.height,
transform: videoElement.style.transform
};
// Apply smooth transition
videoElement.style.transition = 'all 2s ease-in-out';
videoElement.style.width = '60%';
videoElement.style.height = '60%';
videoElement.style.transform = 'translateY(150px) translateX(-200px)';
// Store state for restoration
window.BL.originalState = originalState;
};
const restoreVideoPlayer = async () => {
const videoElement = document.getElementById('player');
const originalState = window.BL.originalState;
// Smooth restoration animation
videoElement.style.transition = 'all 2.5s ease-in-out';
videoElement.style.width = originalState.width;
videoElement.style.height = originalState.height;
videoElement.style.transform = originalState.transform;
// Wait for animation to complete
await new Promise(resolve => setTimeout(resolve, 2500));
};
5. BrightLine SDK Callback Configuration
JavaScript
const setupCallbacks = () => {
// Device information for ad targeting
window.BL.on_deviceInfo = () => ({
frameDivID: 'player-container',
configId: "1018",
applicationName: "MediaTailorDemo",
enableAnalytics: true,
zIndex: "1"
});
// Squeezeback detection callback
window.BL.on_BL_squeezeBack_detected = (data) => {
console.log('Squeezeback animation triggered');
// Custom squeezeback logic here
};
// Ad lifecycle callbacks
window.BL.on_BL_opened = () => console.log('Ad opened');
window.BL.on_BL_closed = () => console.log('Ad closed');
};
6. Countdown Timer for Non-Linear Ads
JavaScript
const countOutOfNonlinearAd = (duration) => {
let countdownValue = Math.round(duration);
// Update UI with initial countdown
setAdCountEvent({
detail: { adCountdown: { toAvailEnd: countdownValue } }
});
// Create countdown interval
const intervalId = setInterval(() => {
countdownValue -= 1;
setAdCountEvent({
detail: { adCountdown: { toAvailEnd: countdownValue } }
});
if (countdownValue <= 0) {
clearInterval(intervalId);
setAdCountDownVisible(false);
}
}, 1000);
return intervalId;
};
7. Complete Integration Example
JavaScript
// Main application setup
const App = () => {
const [mediatailorSession, setMediatailorSession] = useState(null);
useEffect(() => {
// Initialize Datazoom
datazoom.init({ configuration_id: "your-config-id" });
// Initialize BrightLine
BrightlineSDKWrapper.init();
// Create MediaTailor session
const session = await mediatailor.createSession(sessionConfig);
setMediatailorSession(session);
// Set up event listeners
setupEventListeners(session);
}, []);
return (
<div className="player-container">
<video id="player" ref={videoRef} />
{/* Overlay containers for ads */}
</div>
);
};
Key Implementation Notes
Timing: The BrightLine SDK is triggered after Datazoom detects the non-linear ad event
Animation: Squeezeback animations use CSS transitions for smooth visual effects
State Management: Original video state is preserved for proper restoration
Error Handling: Both SDKs include error handling for network and playback issues
Analytics: Tracking events are passed through to maintain ad impression accuracy
Cleanup: Proper cleanup ensures no memory leaks or visual artifacts remain