Skip to main content

Media lists

What you learn​

You're instantiating DIVA Player in your web front-end and relying on DIVA Back Office as the video streaming source.

The goal of this article is to build the simplest front-end to stream a video from the DIVA Back Office. That video comes with some related media lists that front-end users can explore through the DIVA Player menu.

Before starting​

  • Ensure the DIVA Back Office instance you rely on is up and running.
  • Ask your video engineers team the <video id> and the related <settings URL>.
  • Get read-and-write access to the VideoMetadata file.

Defining media lists​

See medialists definition.

Instantiation​

Write the Basic instantiation code. There's no additional code to write, unless you need to manipulate the video list and insert it after the changes.

Working sample code (.tsx)​

Write the App() function to read the VideoMetadataMap as in the following example, and set the mediaLists array:

import {
AssetState,
BoAdapterWebComponentProps,
DivaWebBoAdapter,
VideoMetadata,
} from "@deltatre-vxp/diva-sdk/diva-web-bo-adapter";
import "@deltatre-vxp/diva-sdk/diva-web-sdk/index.min.css";
import { useState } from "react";

const videoId = "<videoId>";

const libs = {
mux: "https://cdnjs.cloudflare.com/ajax/libs/mux.js/6.2.0/mux.min.js",
shaka: "https://ajax.googleapis.com/ajax/libs/shaka-player/4.16.15/shaka-player.compiled.js",
hlsJs: "https://cdn.jsdelivr.net/npm/hls.js@1.5.7",
googleIMA: false,
googleDAI: false,
googleCast: false,
threeJs: false
};

const config = {
videoId: videoId,
libs: libs,
};

function App() {
const [isVideoLive, setIsVideoLive] = useState(false);
const props: BoAdapterWebComponentProps = {
settingsUrl: "<settings URL>",
languageCode: "en-US",
languageDictionary: "en-US",
onDivaBoAdapterError: console.error,
config: config,
// Here integrator can transform the video metadata
videoMetadataMap: async (vd: VideoMetadata) => {
vd.mediaLists = [
{
"listId": "SWITCH",
"rowTitle": "Watch today's matches",
"menuLabel": "diva_switch",
"defaultImageFormat": "tile",
"defaultItemType": "video",
"defaultItemLayout": "vertical",
"noItemsMessage": "No video available at the moment",
"showInEndOfPlay": true,
"items": [
{
"entitledToView": false,
"itemId": "500080_videolist",
"title": "1. Juv Vs Bar",
"caption": "Vod hls-v3",
"imageFormat": "tile",
"itemType": "video",
"itemLayout": "vertical",
"adBadge": true,
"explicitBadge": true,
"ccBadge": true,
"channelLogo": "https://divademo.deltatre.net/channellogo.png",
"channelDescription": "dummy text channelDescription",
"locktext": "Locked"
},
{
"itemId": "500080_v4_videolist",
"title": "2. Juv vs Bar",
"caption": "Vod hls-v4 without data",
"imageFormat": "tile",
"itemType": "video",
"itemLayout": "vertical",
"ccBadge": true,
"adBadge": true,
"explicitBadge": false,
"imageUrl": "https://divademo.deltatre.net/DIVAProduct/www/data/Diva5.0Test/img/2021671.jpg"
},
{
"itemId": "500080_dash_videolist",
"title": "3. Juv vs Bar",
"caption": "Vod Dash with data",
"imageUrl": "https://divademo.deltatre.net/DIVAProduct/www/data/Diva5.0Test/img/@3x/juvvsbar.jpg",
"imageFormat": "tile",
"itemType": "video",
"itemLayout": "vertical",
"adBadge": false,
"explicitBadge": true,
"channelLogo": "https://divademo.deltatre.net/channellogo_ExtremeHorizontal.png",
"lockicon": "https://divademo.deltatre.net/buy-rent.png"
},
{
"itemId": "live_videolist",
"title": "4. Bra Vs Ger - Live",
"caption": "Live hls-v3 with ProgrmamDateTime shifted 20 min after",
"imageFormat": "tile",
"itemType": "video",
"itemLayout": "vertical",
"isLive": true,
"channelLogo": "https://divademo.deltatre.net/channellogo_vertical.png",
"ccBadge": true,
"explicitBadge": true
},
{
"entitledToView": false,
"itemId": "live_v4_videolist",
"title": "5. Bra Vs Ger - Live",
"caption": "Live hls-v4 preroll",
"imageUrl": "https://divademo.deltatre.net/DIVAProduct/www/data/Diva5.0Test/img/@3x/live.png",
"imageFormat": "tile",
"ccBadge": false,
"adBadge": false,
"explicitBadge": false,
"itemType": "video",
"itemLayout": "vertical",
"isLive": true,
"locktext": "Buy or rent",
"channelDescription": "wrong icon path",
"lockicon": "https://divademo.deltatre.net/buy-rent.png",
"channelLogo": "https://divademo.deltatre.net/channellogo-wrong.png"
}
]
}
];
return vd;
},
};

return (
<>
<DivaWebBoAdapter {...props} />
</>
);
}

Customizing the list container (listElementWrapper)​

Each media list accepts an optional, listElementWrapper property. It is a higher-order component function that wraps the entire rendered list container, letting you add custom styling, or additional UI elements without modifying the core list rendering logic.

listElementWrapper?: (element: React.ReactNode) => React.ReactNode;
  • element: The rendered list container element as a React node.
  • returns: A React node containing the wrapped or customized list.
NOTE

listElementWrapper is a runtime React function and therefore cannot be part of the JSON videoMetadata. Add it to the media list object programmatically inside videoMetadataMap.

How to use it​

Add the listElementWrapper function directly to the media list object when building the mediaLists array:

vd.mediaLists = [
{
listId: "SWITCH",
rowTitle: "Watch today's matches",
menuLabel: "diva_switch",
defaultImageFormat: "tile",
defaultItemType: "video",
defaultItemLayout: "vertical",
noItemsMessage: "No video available at the moment",
showInEndOfPlay: true,
items: [
// ...media list items
],
// Optional wrapper to customize the list container rendering
listElementWrapper: (element) => (
<div style={{ padding: "16px", backgroundColor: "#f5f5f5" }}>
{element}
</div>
),
},
];

Examples​

// Add custom styling wrapper
listElementWrapper: (element) => (
<div style={{ padding: "16px", backgroundColor: "#f5f5f5" }}>
{element}
</div>
);
// Combine with a custom component
listElementWrapper: (element) => (
<CustomListContainer>
{element}
</CustomListContainer>
);