Video Player Integration
Native Apps Integration
HTML Webview Breakdown

HTML template breakdown

As mentioned earlier, our video player operates within a web-based environment. The centerpiece of this integration is the HTML template provided below. Before delving into the platform-specific implementation details, let’s carefully dissect the template, step by step, to gain a comprehensive understanding of it. This breakdown will serve as a solid foundation for the subsequent sections.

What can I configure on my video player?

<!DOCTYPE html>
 <html>
   <head>
     <meta charset='UTF-8' />
     <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,viewport-fit=cover" />
     <title>Genius Video Player</title>
   </head>
   <body style='margin: 0;'>
     <div id='container-video' class='container-video'>
         <div id='geniusLive' class='video'></div>
     </div>
   </body>
   <!-- Widget loader script element -->
   <script id='geniusLiveWidgetLoader'></script>

   <!-- Script to start the video player -->
   <script>
       function runVideoplayer() {
           const baseGeniusLivePlayerUrl = '%{baseGeniusLivePlayerUrl}'
           
           // Here we are building the widget loader url and replacing the src attributte of the script element
           document.getElementById('geniusLiveWidgetLoader').src = [
               baseGeniusLivePlayerUrl,
               'customerId=',
               '%{customerId}',
               '&fixtureId=',
               '%{fixtureId}',
               '&containerId=',
               'geniusLive',
               '&width=',
               '%{playerWidth}',
               '&height=',
               '%{playerHeight}',
               '&controlsEnabled=',
               '%{controlsEnabled}',
               '&audioEnabled=',
               '%{audioEnabled}',
               '&allowFullScreen=',
               '%{allowFullScreen}',
               '&bufferLength=',
               '%{bufferLength}',
               '&autoplayEnabled=',
               '%{autoplayEnabled}',
           ].join('')
   
           // Adding listener for geniussportsmessagebus
           window.addEventListener('geniussportsmessagebus', async function (event) {

             if (event.detail.type === 'player_ready') {
               const deliveryType = event.detail.body.deliveryType
               const streamId = event.detail.body.streamId
               const deliveryId = event.detail.body.deliveryId
               const geniusSportsFixtureId = event.detail.body.geniusSportsFixtureId
               const dataToPost = {
                   endUserSessionId: document.cookie, //user session id
                   region: event.detail.body.region, //region
                   device: event.detail.body.device, //device
               }
               // Calling your getSteramingData function to get the streaming info from your backeand
               const data = await getStreamingData(deliveryType, streamId, deliveryId, geniusSportsFixtureId, dataToPost)

               // Please add relevant validation for your backend response
               if (Object.keys(data).length > 0 && !data.ErrorMessage) {
                   GeniusLivePlayer.player.start(data)
               } else {
                   document.getElementById('container-video').style.display = 'none'
               }
             }
             // Get Betslip events
             if (event.detail.type === 'multibet-event') {
               // Android Integration
               if(window.AndroidVideoPlayerBridge){
                   var jsonselectedMarket= JSON.stringify(event.detail.body)
                   window.AndroidVideoPlayerBridge.postSelectedMarket(jsonselectedMarket)
               }
 
               // iOS Integration
               const iOSVideoPlayerBridge = window.webkit?.messageHandlers?.gsVideoPlayerBridge;
               if (iOSVideoPlayerBridge) {
                   const { type, body } = event.detail;
                   iOSVideoPlayerBridge.postMessage({ type, payload: body });
               }
             }
             // Error handling
             if (event.detail.type === 'player_not_ready') {
                 const errorsArray = event.detail.body.error
                 // Add your custom handling here
             }
           })
       }

       async function getStreamingData(deliveryType, streamId, deliveryId, geniusSportsFixtureId, dataToPost) {
           // Here you need to call your backend and retrieve the streaming info based on the given deliveryType, streamId, deliveryId and geniusSportsFixtureId
           return {
               url: 'Video URL',
               expiresAt: 'expiration date',
               token: 'auth token',
               drm: {
                 "fairplay": "https://fairplay-drm-licensing....",
                 "fairplayCertificate": "https://fairplay-certificate....",
                 "playready": "https://playready-drm-licensing....",
                 "widevine": "https://widevine-drm-licensing...."
               },
           }
       }
   
       window.addEventListener('load', runVideoplayer)
   </script>
 </html>

Let's detail the main parts of the HTML template:

Alternatives

This piece of code is an event listener that is triggered when the WebView page has loaded. "load event references: here (opens in a new tab)"

window.addEventListener('load', runVideoplayer)

runVideoplayer: this function handles the logic to initialize the video player

// Handle the logic to initialize the video player
function runVideoPlayer() {
  ...
}

This code embeds the widgetLoader, containing all of the parameters that can be used in the video player widget

const baseGeniusLivePlayerUrl = '%{baseGeniusLivePlayerUrl}'
                
// Here we are building the widget loader url and replacing the src attributte of the script element
document.getElementById('geniusLiveWidgetLoader').src = [
    baseGeniusLivePlayerUrl,
    'customerId=',
    '%{customerId}',
    '&fixtureId=',
    '%{fixtureId}',
    '&containerId=',
    'geniusLive',
    '&width=',
    '%{playerWidth}',
    '&height=',
    '%{playerHeight}',
    '&controlsEnabled=',
    '%{controlsEnabled}',
    '&audioEnabled=',
    '%{audioEnabled}',
    '&allowFullScreen=',
    '%{allowFullScreen}',
    '&bufferLength=',
    '%{bufferLength}',
    '&autoplayEnabled=',
    '%{autoplayEnabled}',
].join('')

This code subscribes to the geniussportsmessagebus event in order to handle messages from the video player widget.

Event types

  • player_ready: Will be triggered in the video player widget when it has loaded, sending the required parameters to start the video player.
  • multibet-event: Will be triggered in the video player widget when the user interacts with the markets.
  • player_not_ready: Will be triggered when an error is detected, it signifies the player's unreadiness for playback. More information here
window.addEventListener('geniussportsmessagebus', async function (event) {
 if (event.detail.type === 'player_ready') {
   const deliveryType = event.detail.body.deliveryType
   const streamId = event.detail.body.streamId
   const deliveryId = event.detail.body.deliveryId
   const geniusSportsFixtureId = event.detail.body.geniusSportsFixtureId
   const dataToPost = {
       endUserSessionId: document.cookie, //user session id
       region: event.detail.body.region, //region
       device: event.detail.body.device, //device
   }
   
   const data = await getStreamingData(deliveryType, streamId, deliveryId, geniusSportsFixtureId, dataToPost)
   // Please add relevant validation for your backend response
   if (Object.keys(data).length > 0 && !data.ErrorMessage) {
       GeniusLivePlayer.player.start(data)
         document.getElementById('container-video').style.display = 'block'
   } else {
       document.getElementById('container-video').style.display = 'none'
   }
 }
 // Get Betslip events
 if (event.detail.type === 'multibet-event') {
   // Android Integration
   if(window.AndroidVideoPlayerBridge){
       var jsonselectedMarket= JSON.stringify(event.detail.body)
       window.AndroidVideoPlayerBridge.postSelectedMarket(jsonselectedMarket)
   }
 
   // iOS Integration
   const iOSVideoPlayerBridge = window.webkit?.messageHandlers?.gsVideoPlayerBridge;
   if (iOSVideoPlayerBridge) {
       const { type, body } = event.detail;
       iOSVideoPlayerBridge.postMessage({ type, payload: body });
   }
 }
 
 // Error handling
 if (event.detail.type === 'player_not_ready') {
     const errorsArray = event.detail.body.error
     // Add your custom handling here
 }
})

getStreamingData: This method should be implemented by each customer calling its own backend and returning a defined structure with the following props in order to start the genius live player widget.

async function getStreamingData(deliveryType, streamId, deliveryId, geniusSportsFixtureId, dataToPost) {
  // Here you need to call your backend and retrieve the streaming info based on the given deliveryType, streamId, deliveryId and geniusSportsFixtureId
  return {
      url: 'Video URL',
      expiresAt: 'expiration date',
      token: 'auth token',
      drm: {
        "fairplay": "https://fairplay-drm-licensing....",
         "fairplayCertificate": "https://fairplay-certificate....",
         "playready": "https://playready-drm-licensing....",
         "widevine": "https://widevine-drm-licensing...."
      }
  }
}

What can I configure on my video player?

If you want to get more details about the properties that can be configured on video player please refer to our web browser integration in the section Video player integration example