Playback rate
Playback rate
Quality
Quality
Captions
Captions
Audio
Audio
"},
config: {"autoplay":true,"captions":"","preload":true,"addrum":true,"showHeatmap":false,"trackView":true,"token":"","muted":false,"loop":false,"expires":0,"playsinline":true,"showSpeed":true,"rememberPosition":null,"forceSettings":false,"t":"","lang":"en","levelCap":false,"chromecast":false,"disableIosPlayer":false,"disableAirPlay":false,"drmEngine":"hls","baseUrl":"https://video.bunnycdn.com","isJit":false,"livePreview":false,"sessionTrackingConfig":{"iframeDomain":"iframe.mediadelivery.net","videoApiHostname":"https://video.bunnycdn.com","serverId":"1235","pullzoneTier":1},"isFairPlay":false,"fairPlayUseHls":false,"enableSchema":true},
startTime: 0,
playbackSpeeds: ["1.00"],
heatmapData: null
};
const PLAYER_SELECTOR = 'bunny-stream-video-ads, bunny-stream-video';
function getPlayerElement() {
return document.querySelector(PLAYER_SELECTOR) || document.querySelector('video');
}
function exposePlayerApi(playerEl) {
if (typeof window.createBunnyPlayerApi !== 'function') {
throw new Error('createBunnyPlayerApi is not available');
}
const playerApi = window.createBunnyPlayerApi(playerEl);
window.player = playerApi;
return playerApi;
}
function initializePlayerJsReceiver(playerEl, playerApi) {
if (typeof window.BunnyPlayerJsReceiver !== 'function') {
throw new Error('BunnyPlayerJsReceiver is not available');
}
const receiver = new window.BunnyPlayerJsReceiver(playerEl, playerApi);
receiver.connect();
}
function initializePlayer() {
const playerEl = getPlayerElement();
const controller = document.querySelector('media-controller');
if (!playerEl || !controller) {
console.error('Required video or media-controller elements not found');
return;
}
const playerApi = exposePlayerApi(playerEl);
initializePlayerJsReceiver(playerEl, playerApi);
}
// Wait for both DOM content and module script to load
const moduleScript = document.querySelector('script[type="module"]');
if (!moduleScript) {
throw new Error('Module script not found');
}
// Create a promise that resolves when the module script loads
const moduleLoaded = new Promise((resolve, reject) => {
moduleScript.addEventListener('load', resolve);
moduleScript.addEventListener('error', reject);
});
// Create a promise that resolves when the DOM is ready
const domReady = new Promise(resolve => {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', resolve);
} else {
resolve();
}
});
// Initialize when both DOM and module are ready
Promise.all([domReady, moduleLoaded])
.then(() => {
requestAnimationFrame(initializePlayer);
// Initialize RUM (Real User Monitoring) if enabled
try {
if (window.RumJob) {
const rumJob = new window.RumJob();
rumJob.start();
} else {
console.warn('RUM tracking requested but RumJob is not available');
}
} catch (error) {
console.error('Failed to initialize RUM:', error);
}
})
.catch(error => {
console.error('Failed to initialize player:', error);
});