Skip to main content

Web Chromeless 5.8

This guide explains how to integrate DIVA Chromeless into your web / webTV application.

Integration demo

A VXP GitHub account is required to gain access to:

What's DIVA Chromeless​

DIVA Chromeless is a player without any kind of UI. It allows the integrator to run streams as usually DIVA does, disabling all the features not strictly related to video playback.
The player is controlled by API.

Note Since there's no UI, DIVA Chromeless Web is suitable for both RW and webTV integration.

Usage examples:​

  • As Page Hero video preview
  • As Video catalog preview

Technical constraints​

  • The player size is not Fullscreen but can fill or fit a defined area of the screen.
  • It doesn't block user interaction on the page (e.g. the player can be an item in a scroll view).
  • It supports only the playback functions without UI on top of the player.
  • Picture in Picture is disabled
  • 360° video and HDR are not supported
  • Multiple player playback on the same screen is not supported.
  • Advertisement is not supported

Requirements​

Our SDK is designed to be used on:

  • Modern browsers:

    • Chrome
    • Firefox
    • Edge (Chromium)
    • Safari
    • Mobile Chrome
    • Mobile Safari
  • SmartTV

    • Tizen 2015 and up
    • WebOS 2.0 and up
  • Sky Boxes

    • Amidala
    • XiOne / Beethoven

The SDK self-contains every dependency except:

  • ReactJS, the host application most provide ReactJS 16+
  • The video player, which loads dynamically based on target device and content type

Provisioning​

The Settings, with which DIVA will be configured.
The VideoMetaData, which provides DIVA with information about the playback for a specific item.

For more information about these items, please consult the Documentation.

This data can be provided as the application developer requires, but will need to return SettingClean and VideoMetaDataClean objects respectively in order to work with the DIVA configuration and initialise the player objects.

For the purpose of this example we will be using raw json, but the provision of the data can be provided from any available source.

We can as an example instantiate a mock 'video' item, from a potential video catalog. Crucial to DIVA 5 is the provision of an ID with which to retrieve settings information and a videoID to retrieve the VideoMetaData.

const videos = {
data: [
{
id: "item-1",
image: "./images/fifa-world-cup.jpg",
title: "France vs Croatia (minimal)",
videoId: "c6455bff-945f-42b2-af99-81dcd5aeba29",
settingId: "full",
},
],
};

Settings​

Setting for the application can be provided in various different formats and are used to provide configuration with which to run a particular video, for example:

Setting Example
{
"general":{
"audioSelectionMethod":"lang",
"closedCaptionSelectionMethod":"lang",
"expectedLiveDuration":3600000,
"increaseLiveDuration":600000,
"isMiddleTimelineEventsLineEnabled":true,
"isTimelineEventsVisibleWithCommentaryOpen":false,
"isVideoThumbnailPreviewEnabled":true,
"jumpLargeGaps":true,
"liveBackOff":30000,
"minimalLayoutWidth":600,
"pipMode":true,
"relevantCommentaryStartsVisible":false,
"resolveManifestUrl":true,
"smallGapLimit":0,
"trackVideoDataManifest":false,
"videoAnalyticsEventFrequency":60000,
"culture":"en-GB"
},
"alerts":{
"alertsPath":"https://<url>/alerts_demo.json",
"displayTime":10000
},
"customPlayByPlay":[
{
"key":"FirstExtraTimeEnd_Big",
"value":"https://<url>/icons/{p.density}/phase_end_big.png"
},
{
"key":"FirstExtraTimeEnd_Mini",
"value":"https://<url>/icons/{p.density}/phase_end_small.png"
},
{
"key":"FirstExtraTimeStart_Big",
"value":"https://<url>/icons/{p.density}/phase_start_big.png"
},
{
"key":"FirstExtraTimeStart_Mini",
"value":"https://<url>/icons/{p.density}/phase_start_small.png"
},
{
"key":"FirstHalfEnd_Big",
"value":"https://<url>/icons/{p.density}/phase_end_big.png"
},
{
"key":"FirstHalfEnd_Mini",
"value":"https://<url>/icons/{p.density}/phase_end_small.png"
},
{
"key":"FirstHalfStart_Big",
"value":"https://<url>/icons/{p.density}/phase_start_big.png"
},
{
"key":"FirstHalfStart_Mini",
"value":"https://<url>/icons/{p.density}/phase_start_small.png"
},
{
"key":"Goal_Big",
"value":"https://<url>/icons/{p.density}/goa_big.png"
},
{
"key":"Goal_Mini",
"value":"https://<url>/icons/{p.density}/goa_small.png"
},
{
"key":"OwnGoal_Big",
"value":"https://<url>/icons/{p.density}/ogo_big.png"
},
{
"key":"OwnGoal_Mini",
"value":"https://<url>/icons/{p.density}/ogo_small.png"
},
{
"key":"PenaltyEnd_Big",
"value":"https://<url>/icons/{p.density}/phase_end_big.png"
},
{
"key":"PenaltyEnd_Mini",
"value":"https://<url>/icons/{p.density}/phase_end_small.png"
},
{
"value":"https://<url>/icons/{p.density}/png_big.png",
"key":"PenaltyGoal_Big"
},
{
"key":"PenaltyGoal_Mini",
"value":"https://<url>/icons/{p.density}/png_small.png"
},
{
"key":"PenaltyStart_Big",
"value":"https://<url>/icons/{p.density}/phase_start_big.png"
},
{
"key":"PenaltyStart_Mini",
"value":"https://<url>/icons/{p.density}/phase_start_small.png"
},
{
"key":"PenaltyWrong_Big",
"value":"https://<url>/icons/{p.density}/ppw_big.png"
},
{
"key":"PenaltyWrong_Mini",
"value":"https://<url>/icons/{p.density}/ppw_small.png"
},
{
"key":"PhasePenaltyGoal_Big",
"value":"https://<url>/icons/{p.density}/ppg_big.png"
},
{
"value":"https://<url>/icons/{p.density}/ppg_small.png",
"key":"PhasePenaltyGoal_Mini"
},
{
"key":"PhasePenaltyWrong_Big",
"value":"https://<url>/icons/{p.density}/ppw_big.png"
},
{
"value":"https://<url>/icons/{p.density}/ppw_small.png",
"key":"PhasePenaltyWrong_Mini"
},
{
"key":"RedCard_Big",
"value":"https://<url>/icons/{p.density}/rc_big.png"
},
{
"key":"RedCard_Mini",
"value":"https://<url>/icons/{p.density}/rc_small.png"
},
{
"key":"SecondExtraTimeEnd_Big",
"value":"https://<url>/icons/{p.density}/phase_end_big.png"
},
{
"key":"SecondExtraTimeEnd_Mini",
"value":"https://<url>/icons/{p.density}/phase_end_small.png"
},
{
"key":"SecondExtraTimeStart_Big",
"value":"https://<url>/icons/{p.density}/phase_start_big.png"
},
{
"key":"SecondExtraTimeStart_Mini",
"value":"https://<url>/icons/{p.density}/phase_start_small.png"
},
{
"key":"SecondHalfEnd_Big",
"value":"https://<url>/icons/{p.density}/phase_end_big.png"
},
{
"key":"SecondHalfEnd_Mini",
"value":"https://<url>/icons/{p.density}/phase_end_small.png"
},
{
"key":"SecondHalfStart_Big",
"value":"https://<url>/icons/{p.density}/phase_start_big.png"
},
{
"key":"SecondHalfStart_Mini",
"value":"https://<url>/icons/{p.density}/phase_start_small.png"
},
{
"key":"Substitution_Big",
"value":"https://<url>/icons/{p.density}/sb_big.png"
},
{
"key":"Substitution_Mini",
"value":"https://<url>/icons/{p.density}/sb_small.png"
},
{
"key":"YellowCard_Big",
"value":"https://<url>/icons/{p.density}/yc_big.png"
},
{
"key":"YellowCard_Mini",
"value":"https://<url>/icons/{p.density}/yc_small.png"
}
],
"ecommerce":{
"feedUrl":"https://<url>/ecommerce/index.html?eventId={v.eventId}&amp;culture={d.culture}",
"wordTag":"shop",
"ecommerceId":"e-commerce",
"iconUrl":"https://<url>/img/shop_icon_white.png",
"toleranceWindow":5000,
"showNotificationsOnce":false
},
"highlights":{
"startMode":"short",
"shortFilter":[
"GOAL",
"OwnGoal",
"PenaltyGoal"
],
"mediumFilter":[
"Goal",
"OwnGoal",
"PenaltyGoal",
"YellowCard",
"RedCard"
],
"longFilter":[
"*"
],
"liveFilter":[
"Goal",
"OwnGoal",
"PenaltyGoal",
"YellowCard",
"RedCard",
"Substitution"
]
},
"liveLike":{
"clientId":"WV6W1rkAJAAXAS9l0LpqHzjDyEcPbuGJjX7Kc2hk",
"chatEnabled":true,
"widgetThemeUrl":"https://<url>/LiveLike/customWidgetThemeUpdated.json"
},
"pushEngine":{
"configUrl":"https://<url>/DIVAProduct/www/Data/DivaDemoIBC/PushEngine/pushengineConfig_HBS.json",
"eCommerceCollectionName":"eCommerceDemo",
"eCommerceCollectionEnabled":false,
"editorialCollectionName":" "
},
"syncDataPanels":{
"dataFolderUrl":"https://<url>/DIVAProduct/www/Data/Diva5.0Test/output/OverlayLiteData/{V.EventId}.{d.Culture}/{OverlayID}.xml",
"renderingFolderUrl":"https://<url>/DIVAProduct/www/Data/Diva5.0Test/output/RenderingLiteData{n:ResourceURI}",
"trustedOrigins":"https://divadoc.deltatre.net,https://<url>"
},
"videoCast":{
"castBackground":"https://<url>/img/diva_chromecast.jpg",
"chromecastAppID":"<appID>"
}
}

Note: setting's sections not specifically related to video playback will be ignored.

For more information about setting and the available options click here.

Dictionary​

No need for dictionary, since there's no UI.

VideoMetaData​

In order to support decoupled OVP provision, DIVA 5 requires that video meta data is retrieved by the integrating application and passed to DIVA 5 as part of the initialisation parameters, an example of which is as follows:

VideoMetadata Example
{
"title":"Video title",
"image":"https://<thumbnail_url>.jpg",
"eventId":"108606",
"programDateTime":"2018-07-15T13:40:15.681Z",
"trimIn":4680858,
"trimOut":11641166,
"ad":"https://<vast_url>/skippable2.xml",
"sources":[
{
"uri":"https://<url>/<video_id>.ism/manifest(format=m3u8-aapl,filter=hls)",
"format":"HLS"
}
],
"audioTracks":[
{
"label":"English",
"id":"English1",
"selector":"English"
}
],
"defaultAudioTrackId":"English1",
"videoLists":[
{
"feedUrl":"https://<url>/rss/108606.xml",
"menu":"Other cameras",
"message":"Watch the live match from different angles",
"behaviour":"multistreamSwitch",
"id":"multistream",
"pollingInterval":30
},
{
"menu":"Other matches",
"message":"Watch other live mathes",
"highlightColor":"0xE65100",
"highlightColorLight":"0xff0000",
"id":"videolist",
"feedUrl":"https://<url>/rss/videolistSwitchDemo.xml"
}
],
"customAttributes":{
"chatId":"444ecf59-dbf2-43db-ae09-99926714022a",
"chatType":"influencer"
},
"recommendation":{
"feedUrl":"https://<url>/rss/videolist_recommendation_short.xml",
"autoLoadTime":0
},
"behaviour":{
"spoilerMode":"highlights"
},
"videoId":"<video_id>"
}
VideoMetadata Provider
// Type definition
export type VideoMetadataProvider = (
videoId: string,
currentVideoMetadata: VideoMetadataClean | undefined,
playbackState?:
| {
chromecast?: boolean | undefined;
hdrMode?: boolean | undefined;
}
| undefined
) => Promise<VideoMetadata>;

// Implementation example
export const requestVideometadata: VideoMetadataProvider = (videoId, currentVideoMetadata, playbackState) => {
videoId = decodeURIComponent(videoId);

const platform = playbackState?.chromecast === true ? 'chromecast' : 'html5';
const hdrType = playbackState?.hdrMode === true ? 'hdr10' : 'none';

const url = `https://<videoMetadataServiceUrl>/${videoId}?platform=${platform}&hdrType=${hdrType}`;

return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();

xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject(new Error(`${this.status} ${xhr.statusText}`));
}
};
xhr.onerror = function () {
reject(xhr.statusText);
};
xhr.send();
});
};

Provision must be done with the same signature as above so that DIVA internally is able to call the VideoMetaData provider and if necessary recall based on interval polling if the application requires data to be refreshed, i.e.

if (!isNaN(divaParams.videoPolling) && divaParams.videoPolling > 0) {
setInterval(function () {
divaAPI.requestVideoMetadataUpdate();
}, divaParams.videoPolling * 1000);
}

With the ability to return VMD, we then have all the elements required to instantiate a DIVA session.

For more information about Video Meta Data please click here.

Entitlement​

Entitlement and Entitlement Provider 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

DIVA Props​

Once the data has been provisioned, we combine the variables into a set of parameters to instantiate DIVA.

PropertyTypeDefaultDescription
Mandatory
config

DivaWebChromelessConfiguration

NAinit config for DIVA
Optional
volumenumber [0-1]1Volume of the player
mutedbooleanfalseWether the player should be muted
videoCoverbooleantrue

If true the player video will fill the space the container otherwise it will fit

adCoverbooleantrue

If true the player advertisement will fill the space the container otherwise it will fit

DivaWebChromelessConfiguration​

PropertyTypeDefaultDescription
Mandatory
videoIdstringNAid of a specific videoMatadata
webTVbooleanNAit specifies if the component is used ina webTV or not
videoMetadataProviderProviderNAFunction used by DIVA to retrieve videoMetadata
libsobjectNA

Object containing the external libraries' url lazy loaded by DIVA only when needed.
Libs reference

Optional
settingSettingNADIVA setting
entitlementProviderentitlementNAFunction used by DIVA to perform entitlement and heartbeat calls
loopbooleanfalseIf true automatic replay is executed when video reaches the end
debugbooleanfalseIt enables debug panel in chromecast
videoDebugbooleanfalseIt enables debug mode of the video libraries (hlsjs / shaka)
detectAdBlockbooleanfalse

If true it raises an error if there's an AD and it's blocked by an ad blocker.

googleImaDAITagParameters{ [key: string]: string }{}

Additional tag params for google DAI.


For example tfua: 1 (Tag For Users under the Age of Consent in Europe) and npa: 1

preferredAudioTrackNamestringNAStarting selector for the audiotracks
preferredCCTrackNamestringNAStarting selector for the closed captions
deepLinkTypestring: 'relative' | 'absolute''relative'

Type of deeplink to apply at startup: relative to the video start (or trimIn) or absolute.

deepLinkValuestring[]

Value of deeplink to apply at startup:
type relative -> number of milliseconds
type absolute -> ISO 8801 datetime.

hdrActivebooleanfalseIt specifies whether to activate HDR or not at startup.
maxBitrateKbpsnumber-1max bitrate in Kbps.
minBitrateKbpsnumber-1min bitrate in Kbps.
startingBitrateKbpsnumber-1starting bitrate in Kbps.
useLastBitratebooleanfalse

if true it makes DIVA using last bitrate from the previous session.

capLevelToPlayerSizebooleanfalseif true it adjusts bitrate depending video size.
shakaConfigOverridesany{}Overrides for shaka video library setup config
hlsJsConfigOverridesany{}Overrides for hls.js video library setup config
useCredentialbooleanfalseUsed by hls.js for xhrSetup.
widevineOverrides

{
requestParams: Record<string, any>;
}

{}Overrides for widevine DRM
fairplayCertificatePathstringNAPath of the fairplay certificate
fairplayOverrides

{
requestQueryParams?: Record<string, string>;
requestHeaders?: Record<string, string>;
skipLicenseRequestParsing?: boolean;
}

{}

Overrides for fairplay DRM: headers, query params, license request parsing

fetchHlsManifestbooleantrue

If true Diva does a fetch to get the Hls manifest and parse it (for example to get the video thumbnails track). Set false to avoid double manifest request.

dataParsingIntervalnumber3000

Pushengine Data parsing interval

unfreezeShakaAtMediaQualityChangesbooleanfalseHack to overcome to Sky XiOne issue that freezes when quality level changes with Harmonic streams. When level switch occurs a micro seek is performed to unfreeze the video.
parameters{ [key: string]: string }undefined

Map of additional keys to add to the path resolver.


Input keys will be saved inside resolver as "settings.<key>"

Callbacks
setAPIfunctionNA

It exposes DIVA APIs
(apiRef: DivaAPI) => void;
API reference

onVideoMetadataChangesfunctionNA

Called when videometadata of the main video changes
(videoMetadata: VideoMetadataClean) => void;

onAnalyticEventfunctionNA

Callback for generic analytic events
(event: GenericEvent) => void;

onMediaAnalyticEventfunctionNA

Callback for media analytic events
(event: MediaEvent) => void;

onPlaybackRatefunctionNA

Called when playback speed of the main video changes
(rate: number) => void;

onPlayerPositionfunctionNA

Called when player position (both relative to the video logical start and unix timecode) of the main video changes

(position: { relativePosition: number; absolutePosition: Date } ) => void;

onPlayerMaxPositionfunctionNA

Called when player max position (both relative to the video logical start and unix timecode) of the main video changes

(position: { relativePosition: number; absolutePosition: Date } ) => void;

onPlayerStatefunctionNA

Called when player state of the main video changes
(state: PlayerState) => void;
PlayerState = 'buffering' | 'end' | 'error' | 'pause' | 'play' | 'unstart';

onVideoErrorfunctionNA

Called on DIVA errors

(error: DivaError, videoMetadata: VideoMetadataClean | undefined) => void;

onVolumefunctionNA

Called when player volume changes
(value: number) => void;

onVideoEndfunctionNA

Called when video end is reached
() => void;

onPlayerActionRequestfunctionNA

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

onPlaybackSessionfunctionNA

Called on DIVA playback session changed.
It returns also a unique identifier of the diva item.

(value: { id: string; playbackSessionId: string }) => void;

DivaWebChromelessConfiguration example
{
videoId: '<videoId>',
webTV: false, // Set it to true if the chromeless player is used inside a webTV app
maxBitrateKbps: -1,
minBitrateKbps: -1,
startingBitrateKbps: -1,
useLastBitrate: false,
useLastBitrate: false,
googleImaDAITagParameters: undefined,
debug: true,
deepLinkType: DeepLinkType.Relative,
deepLinkValue: 1000,
detectAdBlock: false,
fairplayCertificatePath: "",
hdrActive: false,
libs: {
googleCast: "https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1",
googleDAI: "https://imasdk.googleapis.com/js/sdkloader/ima3_dai.js",
googleIMA: "https://imasdk.googleapis.com/js/sdkloader/ima3.js",
hlsJs: "https://cdn.jsdelivr.net/npm/hls.js@1.5.7",
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.11.2/shaka-player.compiled.js",
threeJs: "https://cdnjs.cloudflare.com/ajax/libs/three.js/0.148.0/three.min.js",
},
onAnalyticEvent: console.log,
onMediaAnalyticEvent: console.log,
onPlaybackRate: console.log,
onPlayerActionRequest: console.log,
onPlayerMaxPosition: console.log,
onPlayerPosition: console.log,
onPlayerState: console.log,
onError: console.log,
onVideoMetadataChanges: console.log,
preferredAudioTrackName: "",
preferredCCTrackName: "",
setAPI: (api) => {
// Here you can save a reference to DIVA APIs
window.divaAPI = api;
},
setting: {
general: {
culture: "", // this property is ignored in chromeless mode but it's mandatory in DIVA setting
}
},
useCredential: false,
videoDebug: false,
videoMetadataProvider: (videoId, currentVideoMetadata, playbackState) => {
// returning a Promise of a VideoMetadata
return new Promise((resolve, reject) => {
resolve({
title: "<video_title>",
videoId: '<video_id>',
sources: [
{
format: "HLS",
uri: "https://<url>"
}
],
...
});
});
},
}

Initialization​

Define configuration to use at DIVA instantiation time, combining the data that has been provisioned.

const config: DivaWebChromelessConfiguration = {
videoId: '<videoId>',
libs: {
...
},
setting: {
...
},
gli ...
};
import React, { useEffect, useState } from "react";
import { DivaWebChromelessComponent } from "@deltatre-vxp/diva-sdk/diva-web-chromeless-sdk";

const SETTINGS_URL = "https://example.com/settings";
const VIDEO_METADATA_URL = "https://example.com/metadata";
const VIDEO_ID = "42";

const videoMetadataProvider = async (videoId) => {
return await fetch(`${VIDEO_METADATA_URL}/${videoId}`);
};

const entitlementProvider = async (request) => {
// ...
};

const getSettings = async () => {
const data = await fetch(SETTINGS_URL);
return await data.json();
};

export function App() {
const [config, setConfig] = useState(null);
const [volume, setVolume] = useState(1);
const [muted, setMuted] = useState(false);
const [adCover, setAdCover] = useState(true);
const [videoCover, setVideoCover] = useState(true);

useEffect(() => {
getSettings.then((setting) => {
setConfig({
videoId: VIDEO_ID,
setting,
videoMetadataProvider,
entitlementProvider,
//...
});
});
}, []);

if (!config) {
return null;
}
return (
<div className="app">
<DivaWebChromelessComponent
config={config}
volume={volume}
muted={muted}
videoCover={videoCover}
adCover={adCover}
/>
</div>
);
}

API​

The property setAPI inside DIVA Configuration is intended to be a function that returns an object containing all the APIs for the current DIVA instance.

DIVA API reference list:


/**
* 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;

Logging​

It is possible to attach to DIVA logs or even to use DIVA logger by using onLog config or:

import { LogEntry, onLog, getLogger } from "@deltatre-vxp/diva-sdk/diva-web-chromeless-sdk/index{targetEnv}.js";

// Attach to DIVA logs
const unsubscribe = onLog((log: LogEntry) => {
console.log(log.message, log);
});

// Make use of DIVA logger
const { logDebug, logError, logInfo, logWarning } = getLogger('GENERIC:APP');
logDebug('log message', {
whatever: 'details'
});

// Unsubscribe from DIVA logs
unsubscribe();
note
  • {targetEnv}: .min (production), (empty string) development