Web Chromeless 5.8
This guide explains how to integrate DIVA Chromeless into your web / webTV application.
A VXP GitHub account is required to gain access to:
- Basic Web integration tagged by SDK versions
- Basic WebTV integration tagged by SDK versions.
- Backend integration tagged by SDK versions
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}&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​
- Add
@deltatre-vxp:registry=https://npm.pkg.github.com
to your.npmrc
file - 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.
Property | Type | Default | Description |
---|---|---|---|
Mandatory | |||
config | DivaWebChromelessConfiguration | NA | init config for DIVA |
Optional | |||
volume | number [0-1] | 1 | Volume of the player |
muted | boolean | false | Wether the player should be muted |
videoCover | boolean | true | If true the player video will fill the space the container otherwise it will fit |
adCover | boolean | true | If true the player advertisement will fill the space the container otherwise it will fit |
DivaWebChromelessConfiguration​
Property | Type | Default | Description |
---|---|---|---|
Mandatory | |||
videoId | string | NA | id of a specific videoMatadata |
webTV | boolean | NA | it specifies if the component is used ina webTV or not |
videoMetadataProvider | Provider | NA | Function used by DIVA to retrieve videoMetadata |
libs | object | NA | Object containing the external libraries' url lazy loaded by DIVA only
when needed. |
Optional | |||
setting | Setting | NA | DIVA setting |
entitlementProvider | entitlement | NA | Function used by DIVA to perform entitlement and heartbeat calls |
loop | boolean | false | If true automatic replay is executed when video reaches the end |
debug | boolean | false | It enables debug panel in chromecast |
videoDebug | boolean | false | It enables debug mode of the video libraries (hlsjs / shaka) |
detectAdBlock | boolean | false | 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 |
preferredAudioTrackName | string | NA | Starting selector for the audiotracks |
preferredCCTrackName | string | NA | Starting selector for the closed captions |
deepLinkType | string: 'relative' | 'absolute' | 'relative' | Type of deeplink to apply at startup: relative to the video start (or trimIn) or absolute. |
deepLinkValue | string | [] | Value of deeplink to apply at startup: |
hdrActive | boolean | false | It specifies whether to activate HDR or not at startup. |
maxBitrateKbps | number | -1 | max bitrate in Kbps. |
minBitrateKbps | number | -1 | min bitrate in Kbps. |
startingBitrateKbps | number | -1 | starting bitrate in Kbps. |
useLastBitrate | boolean | false | if true it makes DIVA using last bitrate from the previous session. |
capLevelToPlayerSize | boolean | false | if true it adjusts bitrate depending video size. |
shakaConfigOverrides | any | {} | Overrides for shaka video library setup config |
hlsJsConfigOverrides | any | {} | Overrides for hls.js video library setup config |
useCredential | boolean | false | Used by hls.js for xhrSetup. |
widevineOverrides |
| {} | Overrides for widevine DRM |
fairplayCertificatePath | string | NA | Path of the fairplay certificate |
fairplayOverrides |
| {} | Overrides for fairplay DRM: headers, query params, license request parsing |
fetchHlsManifest | boolean | true | 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. |
dataParsingInterval | number | 3000 | Pushengine Data parsing interval |
unfreezeShakaAtMediaQualityChanges | boolean | false | Hack 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 | |||
setAPI | function | NA | It exposes DIVA APIs |
onVideoMetadataChanges | function | NA | Called when videometadata of the main video changes |
onAnalyticEvent | function | NA | Callback for generic analytic events |
onMediaAnalyticEvent | function | NA | Callback for media analytic events |
onPlaybackRate | function | NA | Called when playback speed of the main video changes |
onPlayerPosition | function | NA | Called when player position (both relative to the video logical start
and unix timecode) of the main video changes
|
onPlayerMaxPosition | function | NA | Called when player max position (both relative to the video logical
start and unix timecode) of the main video changes
|
onPlayerState | function | NA | Called when player state of the main video changes |
onVideoError | function | NA | Called on DIVA errors
|
onVolume | function | NA | Called when player volume changes |
onVideoEnd | function | NA | Called when video end is reached |
onPlayerActionRequest | function | NA | Callback for actions called by API: play, pause, seek, seekBack,
seekFroward, seekPercentage, seekAbsolute |
onPlaybackSession | function | NA | Called on DIVA playback session changed.
|
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 ...
};
- React App
- No React App
- No package manager
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>
);
}
- Add a container for DIVA inside HTML body
<body>
...
<div id="diva-player-container"></div>
...
</body>
- Import Diva into your code
import { createDivaWebChromeless } 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();
};
const el = document.getElementById("diva-player-container");
(async () => {
const setting = await getSettings();
const config = {
videoId: VIDEO_ID,
setting,
videoMetadataProvider,
entitlementProvider,
//...
};
const diva = createDivaWebChromeless(
el,
config,
{
muted: false,
volume: 1,
adCover: true,
videoCover: true
}
});
// DIVA object's functions available
// diva.setStyle({ adCover?: boolean; videoCover?: boolean });
// diva.stop();
})();
Example of integration of DIVA in a simple JavaScript project.
-
Download the DIVA library bundle file
index.bundle[.min].js
.
You can find it under node_modules/@deltatre-vxp/diva-sdk/diva-web-chromeless-sdk. -
Include the js of the library in your HTML file
<head>
...
<script src="path/to/diva.bundle.min.js"></script>
</head>
- Add a container for DIVA inside HTML body
<body>
...
<div id="diva-player-container"></div>
...
</body>
- Instantiate DIVA
//...
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();
};
const el = document.getElementById("diva-player-container");
(async () => {
const setting = await getSettings();
const config = {
videoId: VIDEO_ID,
setting,
videoMetadataProvider,
entitlementProvider,
//...
};
if(divaInstance) {
// Correctly unmount previous DIVA instance
divaInstance.stop();
}
divaInstance = divaWebChromelessSdk.createDivaWebChromeless(
el,
config,
{
muted: false,
volume: 1,
adCover: true,
videoCover: true
}
});
// DIVA object's functions available
// diva.setStyle({ adCover?: boolean; videoCover?: boolean });
// diva.stop();
})();
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:
- With package manager
- No package manager
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();
<html>
<head>
<!-- ... -->
<script src="path/to/diva/index.bundle{targetEnv}.js"></script>
</head>
<body>
<!-- ... -->
<script>
const { onLog, getLogger } = divaWebTv;
// Attach to DIVA logs
const unsubscribe = onLog((log) => {
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();
</script>
</body>
</html>
{targetEnv}
:.min
(production),