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.
To review a complete example (HLS.js + AWS MediaTailor + Datazoom Analytics + Brightline) and full list of available methods, callback parameters, and advanced configuration options, refer to the BrightLine SDK Reference Docs.
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
1// Initialize Datazoom with MediaTailor session23const context = datazoom.createContext(hlsPlayer, {45 adapterOptions: { hlsClass: Hls }67});89context.attachMediaTailorSession(session);1011// Set up event listeners for non-linear ads1213session.addEventListener(mediatailor.SessionUiEvent.NONLINEAR_AD_START, event => {1415 handleNonLinearAdStart(event.detail?.nonLinearAdsObject);1617 videoElement.controls = false; // Hide video controls during ad1819});2021session.addEventListener(mediatailor.SessionUiEvent.NONLINEAR_AD_END, event => {2223 handleNonLinearAdEnd(event.detail?.nonLinearAdsObject);2425 videoElement.controls = true; // Restore video controls2627});2. Non-Linear Ad Start Handler
JavaScript
1const handleNonLinearAdStart = async (event) => {23 // Extract ad data from the event45 const { nonLinearAdList, trackingEvents, duration } = event.adData;67 const nonLinearAd = nonLinearAdList[0];89 1011 // Create tracking data for analytics1213 const trackingNodeStr = JSON.stringify({1415 trackingEvents: {1617 createView: trackingEvents1819 .filter(event => event.eventType === 'impression')2021 .map(event => event.beaconUrls)2223 .flat()2425 }2627 });2829 3031 // Trigger BrightLine SDK to show overlay3233 await BrightlineSDKWrapper.openAd(3435 nonLinearAd.iFrameResource, // Ad content URL3637 'player', // Video element ID3839 true, // Enable close button4041 'channel-name', // Channel identifier4243 trackingNodeStr, // Tracking data4445 duration // Ad duration in seconds4647 );4849};3. BrightLine SDK Wrapper Core Methods
JavaScript
1const BrightlineSDKWrapper = {23 // Initialize the SDK45 init: async () => {67 await loadBrightlineScript();89 setupEventCallbacks();1011 },1213 // Open an overlay ad with squeezeback animation1415 openAd: async (src, playerId, enableClose, channel, tracking, duration) => {1617 // Load the overlay content1819 window.BL.openAd(src, playerId, enableClose, channel, tracking, duration);2021 2223 // Trigger custom squeezeback animation2425 setTimeout(() => {2627 triggerSqueezebackAnimation(playerId, duration);2829 }, 100);3031 },3233 // Close ad and restore video3435 closeAd: async () => {3637 await restoreVideoPlayer();3839 window.BL.closeAd();4041 }4243};4. Squeezeback Animation Implementation
JavaScript
1const triggerSqueezebackAnimation = (playerId, duration) => {23 const videoElement = document.getElementById(playerId);45 67 // Store original video state89 const originalState = {1011 width: videoElement.style.width,1213 height: videoElement.style.height,1415 transform: videoElement.style.transform1617 };1819 2021 // Apply smooth transition2223 videoElement.style.transition = 'all 2s ease-in-out';2425 videoElement.style.width = '60%';2627 videoElement.style.height = '60%';2829 videoElement.style.transform = 'translateY(150px) translateX(-200px)';3031 3233 // Store state for restoration3435 window.BL.originalState = originalState;3637};3839const restoreVideoPlayer = async () => {4041 const videoElement = document.getElementById('player');4243 const originalState = window.BL.originalState;4445 4647 // Smooth restoration animation4849 videoElement.style.transition = 'all 2.5s ease-in-out';5051 videoElement.style.width = originalState.width;5253 videoElement.style.height = originalState.height;5455 videoElement.style.transform = originalState.transform;5657 5859 // Wait for animation to complete6061 await new Promise(resolve => setTimeout(resolve, 2500));6263};5. BrightLine SDK Callback Configuration
JavaScript
1const setupCallbacks = () => {23 // Device information for ad targeting45 window.BL.on_deviceInfo = () => ({67 frameDivID: 'player-container',89 configId: "1018",1011 applicationName: "MediaTailorDemo",1213 enableAnalytics: true,1415 zIndex: "1"1617 });1819 // Squeezeback detection callback2021 window.BL.on_BL_squeezeBack_detected = (data) => {2223 console.log('Squeezeback animation triggered');2425 // Custom squeezeback logic here2627 };2829 // Ad lifecycle callbacks3031 window.BL.on_BL_opened = () => console.log('Ad opened');3233 window.BL.on_BL_closed = () => console.log('Ad closed');3435};6. Countdown Timer for Non-Linear Ads
JavaScript
1const countOutOfNonlinearAd = (duration) => {23 let countdownValue = Math.round(duration);45 67 // Update UI with initial countdown89 setAdCountEvent({1011 detail: { adCountdown: { toAvailEnd: countdownValue } }1213 });1415 1617 // Create countdown interval1819 const intervalId = setInterval(() => {2021 countdownValue -= 1;2223 setAdCountEvent({2425 detail: { adCountdown: { toAvailEnd: countdownValue } }2627 });2829 3031 if (countdownValue <= 0) {3233 clearInterval(intervalId);3435 setAdCountDownVisible(false);3637 }3839 }, 1000);4041 4243 return intervalId;4445};7. Complete Integration Example
JavaScript
1// Main application setup23const App = () => {45 const [mediatailorSession, setMediatailorSession] = useState(null);67 89 useEffect(() => {1011 // Initialize Datazoom1213 datazoom.init({ configuration_id: "your-config-id" });1415 1617 // Initialize BrightLine1819 BrightlineSDKWrapper.init();2021 2223 // Create MediaTailor session2425 const session = await mediatailor.createSession(sessionConfig);2627 setMediatailorSession(session);2829 3031 // Set up event listeners3233 setupEventListeners(session);3435 }, []);3637 3839 return (4041 <div className="player-container">4243 <video id="player" ref={videoRef} />4445 {/* Overlay containers for ads */}4647 </div>4849 );5051};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