Skip to main content

Web Chromeless BO Adapter 5.7

This guide explains how to integrate DIVA Chromeless with DIVA BO using DIVA BoAdapter into your web / webTV application. application.

Requirements​

Refer to DIVA Web Chromeless SDK documentation.

SDK Setup​

  1. Add @deltatre-vxp:registry=https://npm.pkg.github.com to your .npmrc file
  2. Install the SDK
       npm install @deltatre-vxp/diva-sdk

Initialization​

Diva BO Adapter gives programmatic access to the standard providers and to common plugins used by the DIVA player SDK when connected to DIVA BO.

import React, { useEffect, useState } from "react";

// bo adapter sdk
import { DivaChromelessBoAdapter } from "@deltatre-vxp/diva-sdk/diva-web-chromeless-bo-adapter";

// bo settings link
const SETTINGS_URL = "https://example.com/settings.json";

// id of the video to be runned
const VIDEO_ID = "123456789890";

const isWebTV = false;

const muted = false;
const volume = 1;

const config = {
videoId:VIDEO_ID,
webTv: isWebTV,
libs: {
mux: 'https://cdnjs.cloudflare.com/ajax/libs/mux.js/6.2.0/mux.min.js',
shaka: 'https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.8.5/shaka-player.compiled.js',
hlsJs: 'https://cdn.jsdelivr.net/npm/hls.js@1.5.7',
googleIMA: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',
googleDAI: 'https://imasdk.googleapis.com/js/sdkloader/ima3_dai.js',
googleCast: 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1',
threeJs: 'https://cdnjs.cloudflare.com/ajax/libs/three.js/0.148.0/three.min.js',
}
};

export const App = () => (
<DivaChromelessBoAdapter
settingsUrl={SETTINGS_URL}
config={config}
muted={muted}
volume={volume}
/>
)

Properties​

PropertyTypeDefaultDescription
Mandatory
Property: settingsUrltype:
string
Default: NAurl to reach diva bo adapter settings for the specific project
Property: configtype:Default: NAinitialization data for DIVA BO adapter
Property: el (vanilla js/react embedded)type:
HTML div element reference
Default: NAHTML div element where diva should be started into
Optional
Property: mutedtype:
boolean
Default: falseif trues it starts the adapter muted
Property: volumetype:
number
Default: 1starting volume [0-1]
Property: adCovertype:
boolean
Default: trueit says if the advertisement should fit or fill the chromeless container. Default fill.
Property: videoCovertype:
boolean
Default: trueit says if the video should fit or fill the chromeless container. Default fill.
Property: mediaAnalyticsParamtype:Default: undefinedproperties useful to implement media analytics
Property: entitlementConfigurationtype:Default: undefinedproperties useful to implement entitlement
Middleware
Property: videoMetadataMaptype:
(videoMetadata: VideoMetadata) => Promise<VideoMetadata>
Default: undefinedasynchronous middleware for the app to interact and modify the videoMetadata as soon as videoMetadata is returned from the request (passthrough if not defined)
Callbacks
Property: onDivaBoAdapterErrortype:
(e: unknown) => void
Default: undefinednotify errors on bo adapter start (React)

Typescript interfaces for Properties​

ChromelessBoAdapterWebComponentProps and ChromelessBoAdapterWebVanillaProps
interface ChromelessBoAdapterWebComponentProps {
/**
* url to reach diva bo adapter settings for the specific project
*/
settingsUrl: string;
/**
*
*/
onDivaBoAdapterError?: OnDivaBoAdapterError;

/**
* a middleware for the app to interact and modify the videoMetadata as soon as videoMetadata is returned from the request (passthrough if not defined)
*/
videoMetadataMap?: VideoMetadataMap;

/**
*properties useful to implement media analytics
*/
mediaAnalyticsParam?: MediaAnalyticsProps;

/**
*properties useful to implement entitlement
*/
entitlementConfiguration?: EntitlementConfiguration;

/**
* initialization config for DIVA BO adapter
*/
config: BoAdapterWebComponentConfig;

/**
* starting muted
*/
muted?: boolean;

/**
* starting volume [0-1]
*/
volume?: number;

/**
* it says if the advertisement should fit or fill the chromeless container. Default fill.
*/
adCover?: boolean;

/**
* it says if the video should fit or fill the chromeless container. Default fill.
*/
videoCover?: boolean;
}

interface ChromelessBoAdapterWebVanillaProps
extends Omit<ChromelessBoAdapterWebComponentProps, "onDivaBoAdapterError"> {
el: HTMLElement;
}

Config​

BO Adapter config are the same as those in the DIVA Chromeless SDK, excluding for videoMetadataProvider, dictionary, entitlementProvider, setting, fairplayCertificatePath properties, because they are provided by BO adapter.

PropertyTypeDefaultDescription
Mandatory
Property: videoIdtype:
string
Default: NAid of the video to play
Property: webTVtype:
boolean
Default: NAit specifies if the component is used ina webTV or not
Property: libstype:Default: NAlibraries required
Optional
Property: looptype:
boolean
Default: falseIf true automatic replay is executed when video reaches the end
Property: debugtype:
boolean
Default: falseIt enables debug panel in chromecast
Property: videoDebugtype:
boolean
Default: falseIt enables debug mode of the video libraries (hlsjs / shaka)
Property: detectAdBlocktype:
boolean
Default: falseIf true it raises an error if there's an AD and it's blocked by an ad blocker.
Property: googleImaDAITagParameterstype:
{ [key: string]: string }
Default: {}Additional tag params for google DAI. For example tfua: 1 (Tag For Users under the Age of Consent in Europe) and npa: 1
Property: preferredCCTrackNametype:
string
Default: undefinedCC track to start with (if present)
Property: preferredAudioTrackNametype:
string
Default: undefinedAudio track to start with (if present)
Property: deepLinkTypetype:
DeepLinkType
Default: NAtype of the deep link
Property: deepLinkValuetype:
string
Default: undefinedvalue of the deep link in milliseconds
Property: hdrActivetype:
boolean
Default: falseif HDR is enabled or not
Property: maxBitrateKbpstype:
number
Default: -1max bitrate in Kbps
Property: minBitrateKbpstype:
number
Default: -1min bitrate in Kbps
Property: startingBitrateKbpstype:
number
Default: -1starting bitrate in Kbps
Property: useLastBitratetype:
boolean
Default: falseif true it makes DIVA using last bitrate from the previous session
Property: capLevelToPlayerSizetype:
boolean
Default: falseif true it adjusts bitrate depending video size
Property: hlsJsConfigOverridestype:
any
Default: undefined--
Property: shakaConfigOverridestype:
any
Default: undefined--
Property: useCredentialtype:
boolean
Default: falseUsed by hls.js for xhrSetup.
Property: widevineOverridestype:
{ requestParams: Record<string, any>}
Default: {}Overrides for widevine DRM
Property: fairplayCertificatePathtype:
string
Default: NAPath of the fairplay certificate
Property: fairplayOverridestype:
{
 requestQueryParams?: Record<string, string>;
 requestHeaders?: Record<string, string>;
 skipLicenseRequestParsing?: boolean;
}
Default: {}Overrides for fairplay DRM: headers, query params, license request parsing
Property: parameterstype:
[key: string]: string
Default: undefinedMap of additional keys to add to the path resolver. Input keys will be saved inside resolver as "settings.<key>"
Callbacks
Property: setAPItype:
(apiRef: DivaAPI) =>  void
Default: undefinedprovide as soon as possible an imperative api to interact with the player
Property: onVideoMetadataChangestype:
(videoMetadata: VideoMetadataClean) => void
Default: undefinedCalled when videometadata of the main video changes
Property: onVideoErrortype:
(error: DivaError, videoMetadata: VideoMetadataClean) => void
Default: undefinedCalled on DIVA errors
Property: onEventtype:
(event: { type: 'BACK_PRESS_OUTSIDE' }) => boolean | Promise<boolean>
Default: undefinedactually used only for cases when the user is leaving the player with BACK_PRESS_OUTSIDE
Property: onAnalyticEventtype:
(event: GenericEvent)  =>  void
Default: undefinednotify analytics events
Property: onMediaAnalyticEventtype:
(event: MediaEvent)  =>  void
Default: undefinednotify media analytics events
Property: onPlayerPositiontype:
(position: { relativePosition: number; absolutePosition: Date }) => void
Default: undefinednotify as frequent as possible the position reached by the player in the playing video
Property: onPlayerMaxPositiontype:
(position: { relativePosition: number; absolutePosition: Date }) => void
Default: undefinedCalled when player max position (both relative to the video logical start and unix timecode) of the main video changes
Property: onPlaybackRatetype:
(rate: number) => void
Default: undefinedCalled when playback speed of the main video changes
Property: onPlayerStatetype:
(state: PlayerState) => void;
Default: undefinedCalled when player state of the main video changes. PlayerState = 'buffering' | 'end' | 'error' | 'pause' | 'play' | 'unstart';
Property: onVolumetype:
(value: number) => void;
Default: undefinedCalled when player volume changes
Property: onVideoEndtype:
()=>void
Default: undefinednotify when the playing video reaches the end
Property: onPlayerActionRequesttype:
(value: DivaAction) => void;
Default: undefinedCallback for actions called by API: play, pause, seek, seekBack, seekFroward, seekPercentage, seekAbsolute

Typescript interfaces for Config​

BoAdapterWebComponentConfig
interface DivaWebChromelessConfiguration {
// WEB TV
// ========================================================================
videoId: string;

// WEB TV
// ========================================================================
webTv: boolean;

// DEBUG
// ========================================================================
debug?: boolean;
videoDebug?: boolean;

// AD
// ========================================================================
detectAdBlock?: boolean;
/**
* Additional tag params for google DAI
* For example tfua: 1 (Tag For Users under the Age of Consent in Europe) and npa: 1
*/
googleImaDAITagParameters?: unknown;

// LAZY LOADED LIBS
// ========================================================================
libs: Libs;

// AUDIO AND CC
// ========================================================================
preferredAudioTrackName?: string;
preferredCCTrackName?: string;

// DEEP LINK
// ========================================================================
deepLinkType?: DeepLinkType;
deepLinkValue?: number | string;

// HDR
// ========================================================================
hdrActive?: boolean;

// BITRATE LIMITATIONS
// ========================================================================
maxBitrateKbps?: number;
minBitrateKbps?: number;
startingBitrateKbps?: number;
maxVideoWidth?: number;
useLastBitrate?: boolean;
capLevelToPlayerSize?: boolean;

// SETTING AND PROVIDERS
// ========================================================================
setting: Setting;
videoMetadataProvider: VideoMetadataProvider;
entitlementProvider?: EntitlementProvider;

// MEDIA PLAYER CONFIGS
// ========================================================================
// eslint-disable-next-line @typescript-eslint/no-explicit-any
hlsJsConfigOverrides?: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
shakaConfigOverrides?: any;
useCredential?: boolean;
widevineOverrides?: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
requestParams: any;
};
fairplayCertificatePath?: string;
fairplayOverrides?: {
requestQueryParams?: Record<string, string>;
requestHeaders?: Record<string, string>;
skipLicenseRequestParsing?: boolean;
};
unfreezeShakaAtMediaQualityChanges?: boolean;



loop?: boolean;

// CALLBACKS
// ========================================================================

/**
* It exposes DIVA APIs
*/
setAPI?: (apiRef: DivaWebChromelessAPI) => void;

/**
* Logs callback
*/
// onLog?: (log: LogEntry) => void;

/**
* VideoMetadataChanges callback
*/
onVideoMetadataChanges?: (videoMetadata: VideoMetadataClean) => void;

/**
* Callback for generic analytic events
*/
onAnalyticEvent?: (event: GenericEvent) => void;

/**
* Callback for media analytic events
*/
onMediaAnalyticEvent?: (event: MediaEvent) => void;

/**
* Called when playback speed of the video changes
*/
onPlaybackRate?: (rate: number) => void;

/**
* Callback for actions called by API: play, pause, seek, seekBack, seekFroward, seekPercentage, seekAbsolute
*/
onPlayerActionRequest?: (value: DivaAction) => void;

/**
* Called when player position (both relative to the video logical start and unix timeCode) of the video changes
*/
onPlayerPosition?: (position: { relativePosition: number; absolutePosition: Date }) => void;

/**
* Called when player max position (both relative to the video logical start and unix timeCode) of the video changes
*/
onPlayerMaxPosition?: (position: { relativePosition: number; absolutePosition: Date }) => void;

/**
* Called when player state of the video changes
*/
onPlayerState?: (state: PlayerState) => void;

/**
* Called in case of errors
*/
onError?: (error: DivaError, videoMetadata: VideoMetadataClean | undefined) => void;

/**
* Called when video end is reached
*/
onVideoEnd?: () => void;

/**
* Called in case of volume changes
*/
onVolume?: (volume: number) => void;
}


type BoAdapterWebComponentConfig = Omit<
DivaWebChromelessConfiguration,
'videoMetadataProvider' | 'dictionary' | 'entitlementProvider' | 'setting' | 'fairplayCertificatePath'
>;

Entitlement​

PropertyTypeDefaultDescription
Optional
Property: entitlementPlatformtype:
string
Default: ""platform parameter used to request entitlement token
Property: otherParameterstype:
Record<string, string>
Default: ""other parameters used to request entitlement token
Property: entitlementPlayerTypetype:
string
Default: ""player type parameter used to request entitlement token
Middlewares
Property: entitlementUsertype:
(data) => string
Default: undefineda middleware to provide user token when requested

Typescript interfaces for Entitlement configuration​

BoEntitlementConfiguration
interface BoEntitlementConfiguration {
/**
* platform parameter used to request entitlement token
*/
entitlementPlatform?: string;
/**
*
*/
otherParameters?: Record<string, string>;
/**
* function that returns the user token
*/
entitlementUser?: () => string;
/**
* default to "HTML5", used in the entitlement "PlayerType" request parameter
*/
entitlementPlayerType?: string;
}

Media Analytics​

PropertyTypeDefaultDescription
Optional
Property: viewerIdtype:
string
Default: ""viewer id passed down to media analytics platforms
Property: userNametype:
string
Default: ""user name passed down to media analytics platforms
Property: playerVersiontype:
string
Default: ""player version parameter passed down to media analytics platforms
Property: playerTypetype:
string
Default: ""player type parameter passed down to media analytics platforms
Property: cdnNametype:
string
Default: ""cdn name parameter passed down to media analytics platforms
Property: omLibstype:
object
Default: undefinedIt's an object of type:
{omWeb: string; omSessionClient: string;}.
It contains the libs urls for OpenMeasurement hosted by project.
It's mandatory to make OM work.
Download libs files
Callbacks
Property: mediaAnalyticsEventHandlertype:
(event: MediaEvent)  =>  void
Default: undefinedadditional callback for notifying media analytics events
Middlewares
Property: customTagtype:
(videoMetadata: VideoMetadataClean)  => Record<string, string>
Default: undefinedcustom tag generator
Property: customDimensionstype:
(videoMetadata: VideoMetadataClean) => string[]
Default: undefinedcustom dimensions generator
Property: customDeviceMetadatatype:Default: undefinedcustom device metadata generator for Conviva

Typescript interfaces for Media Analytics Configuration​

MediaAnalyticsProps
export interface MediaAnalyticsProps {
/**
* custom tag generator
*/
customTag?: CustomTagGenerator;

/**
* custom dimensions
*/
customDimensions?: CustomDimensionsGenerator;

/**
* custom device metadata generator for Conviva
*/
customDeviceMetadata?: CustomDeviceMetadataGenerator;

/**
* additional callback for media analytics events.
*/
mediaAnalyticsEventHandler?: OnMediaAnalyticsEventHandler;

/**
* viewer id passed down to media analytics platforms
*/
viewerId?: string;

/**
* user name passed down to media analytics platforms
*/
userName?: string;

/**
* player version passed down to media analytics platforms
*/
playerVersion?: string;

/**
* player type parameter passed down to media analytics platforms
*/
playerType?: string;

/**
* cdn name parameter passed down to media analytics platforms
*/
cdnName?: string;

/**
* urls for OpenMeasurement libs hosted by project
*/
omLibs?: {
omWeb: string;
omSessionClient: string;
};
}

DivaAPI​

Imperative API to interact with the player.

Typescript interfaces for DIVA API​

DIVA API

/**
* It will force DIVA to request a new VideoMetadata through videoMetadataProvider
*/
requestVideoMetadataUpdate: () => void;

// Getters

/**
* It returns the player position (both relative to the video logical start and unix timeCode as Date) of the video.
*/
getPlayerPosition: (videoId?: string) => { relative: number; absolute: Date };

/**
* It returns the player duration (both relative to the video logical duration and absolute end point as a Date) of the video.
*/
getPlayerDuration: (videoId?: string) => { relative: number; absolute: Date };

/**
* It returns the current video playback rate.
*/
getPlaybackRate: () => number;

/**
* It returns the current video state. Possible value: 'buffering', 'end', 'error', 'pause', 'play', 'unstart'.
*/
getPlayerState: () => PlayerState;

/**
* It returns the current video volume. Values could be from 0 to 1.
*/
getVolume: () => number;

/**
* It returns the Diva version in this format: 'major.minor.patch'.
*/
getVersion: () => string;

// Actions

/**
* It mute/unmute the video.
* @param value boolean, true to mute, false to unmute.
*/
mute: (value: boolean) => void;

/**
* It pauses video playback.
* @param interactive boolean, for analytics track, true if with user interaction.
*/
pause: (interactive?: boolean) => void;

/**
* It starts the video playback.
* @param interactive boolean, for analytics track, true if with user interaction.
* @returns the videoElement play promise.
*/
play: (interactive?: boolean) => Promise<void>;

/**
* It seeks the video playback.
* @param value number, milliseconds value relative to the video start time.
* @param interactive boolean, for analytics track, true if with user interaction.
* @returns A promise usefull to check when the action is done.
*/
seek: (value: number, interactive?: boolean) => Promise<void>;

/**
* It seeks back the video playback by the value get from videoMetadata.behaviour.seekInterval. Default 10 seconds.
* @param interactive boolean, for analytics track, true if with user interaction.
* @returns A promise usefull to check when the action is done.
*/
skipBack: (interactive?: boolean) => Promise<void>;

/**
* It seeks forward the video playback by the value get from videoMetadata.behaviour.seekInterval. Default 10 seconds.
* @param interactive boolean, for analytics track, true if with user interaction.
* @returns A promise usefull to check when the action is done.
*/
skipForward: (interactive?: boolean) => Promise<void>;

/**
* It seeks the video playback by percentage.
* @param value number, percentage from 0 to 100.
* @param interactive boolean, for analytics track, true if with user interaction.
* @returns A promise usefull to check when the action is done.
*/
seekPercentage: (value: number, interactive?: boolean) => Promise<void>;

/**
* It seeks the video playback by Date object.
* @param value Date, in ISO 8601 format. (YYYY-MM-DDThh:mm:ssZ)
* @param interactive boolean, for analytics track, true if with user interaction.
* @returns A promise usefull to check when the action is done.
*/
seekAbsolute: (value: Date, interactive?: boolean) => Promise<void>;

/**
* It sets the rate at which the video is being played back.
* @param value number, a value of 1 indicates normal speed.
*/
setPlaybackRate: (value: number) => void;

/**
* It sets the video volume.
* @param value number, from 0 to 1, where 0 is effectively muted and 1 is the loudest possible value.
*/
setVolume: (value: number) => void;

/**
* Fires an event of the specified type with an optional payload.
* Used for Ad beaconing.
* @param type - The type of the event.
* @param payload - The payload associated with the event.
*/
fireEvent: (type: AnalyticsMediaEventType, payload?: { ad: Ad }) => void;

// Exposed path resolver
resolve(
value: string,
options?: {
; // if not provided it will fallback to main item
data?: Record<string, string>;
dontApplyDefault?: boolean;
}
): string;

Single command entry point for: mute, pause, play, set playback rate, seek, seek absolute

sendPlayerCommand: (command: DivaCommand, interactive: boolean) => void | Promise<void>;

// DIVA Commands interfaces
export enum DivaCommandName {
MUTE = 'mute',
PAUSE = 'pause',
PLAY = 'play',
PLAYBACK_RATE = 'playback-rate',
SEEK = 'seek',
SEEK_ABSOLUTE = 'seek-absolute',
}

interface DivaCommandBase {
;
command: DivaCommandName;
}

export interface DivaCommandMute extends DivaCommandBase {
command: DivaCommandName.MUTE;
value: boolean;
}

export interface DivaCommandPause extends DivaCommandBase {
command: DivaCommandName.PAUSE;
}

export interface DivaCommandPlay extends DivaCommandBase {
command: DivaCommandName.PLAY;
}

export interface DivaCommandPlaybackRate extends DivaCommandBase {
command: DivaCommandName.PLAYBACK_RATE;
value: number;
}

export interface DivaCommandSeek extends DivaCommandBase {
command: DivaCommandName.SEEK;
value: number; // Milliseconds relative to trim in
}

export interface DivaCommandSeekAbsolute extends DivaCommandBase {
command: DivaCommandName.SEEK_ABSOLUTE;
value: Date;
}

export type DivaCommand =
| DivaCommandMute
| DivaCommandPause
| DivaCommandPlay
| DivaCommandPlaybackRate
| DivaCommandSeek
| DivaCommandSeekAbsolute;

Libs​

Object containing the external libraries' url lazy loaded only when needed by DIVA Web SDK.

The following block of code is an example of value pointing to public CDNs.

{
// video libraries
hlsJs: 'https://cdn.jsdelivr.net/npm/hls.js@1.5.7',
shaka: 'https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.8.5/shaka-player.compiled.js',
mux: 'https://cdnjs.cloudflare.com/ajax/libs/mux.js/6.2.0/mux.min.js',

// Advertisement
googleIMA: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',
googleDAI: 'https://imasdk.googleapis.com/js/sdkloader/ima3_dai.js',

// Chromecast
googleCast: 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1',

// Used for 360 videos
threeJs: 'https://cdnjs.cloudflare.com/ajax/libs/three.js/0.148.0/three.min.js',
}

Disable Lazy Loading​

DIVA allows skipping the lazy loading of a third-party library by inserting the value 'false' (boolean) instead of the string containing the library's URL.
By doing so, the player assumes that the library has already been loaded and avoids loading it again.
This can improve startup performances.
Note: It is the integrator's responsibility to ensure the preloading of the necessary libraries.

Example disabling lazy loading for shaka and mux

{
// video libraries
hlsJs: 'https://cdn.jsdelivr.net/npm/hls.js@1.0.4',
shaka: false,
mux: false,

// Advertisement
googleIMA: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',
googleDAI: 'https://imasdk.googleapis.com/js/sdkloader/ima3_dai.js',

// Chromecast
googleCast: 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1',

// Used for 360 videos
threeJs: 'https://cdnjs.cloudflare.com/ajax/libs/three.js/0.148.0/three.min.js',
}