Multiview
The previous implementation is deprecated and will be maintained only until version 5.13.x. After that, it will no longer be supported. Upgrade now to ensure continued compatibility.
This feature displays a horizontal list of media items during playback, allowing users to navigate and select additional media streams to watch together.


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 with enabled multiview.
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>
. - Ensure the VideoMetadata contains the media lists data.
- Ensure the VideoMetadata
behavior
ismultiview
(default). - Ensure the VideoMetadata
rowTitle
andmenuLabel
are translated in the dictionary.
Instantiation​
Write the Basic instantiation code. There's no additional code to write, unless you need to overwrite the autoplay behavior that the VideoMetadata contains.
The Multiview mode is available also if at least one of the videolist item inside videoMetadata has as behavior
"multiview" or "multistreamMultiview". In that case, the multiview button will appear in the bottom right corner of the player, and the user can add/remove videos from the multiview list.
When the multiview is enabled the icon to change the selection of the videos is displayed at the center.
The icon displayed can't be customized but the label could be traslated in the dictionary as diva_multiview_videolist_button_title
.

Working sample code (.tsx)​
import React from "react";
import { DivaWebBoAdapter } from "@deltatre-vxp/diva-sdk/diva-web-bo-adapter";
import "@deltatre-vxp/diva-sdk/diva-web-sdk/index.min.css";
const videoId = "<videoId1>";
const 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.11.2/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
};
const props = {
settingsUrl: "<Settings URL>",
languageCode: "en-US",
languageDictionary: "en-US",
onDivaBoAdapterError: console.error,
config: config
}
function App() {
const [isVideoLive, setIsVideoLive] = useState(false);
const props: BoAdapterWebComponentProps = {
settingsUrl: "<settings URL>",
languageCode: "en-US",
languageDictionary: "en-US",
onDivaBoAdapterError: console.error,
config: config,
videoMetadataMap: async (vd: VideoMetadata) => {
vd.mediaLists = [
{
listId:"xxxxxx",
rowTitle:"diva_watch_other_video",
defaulImageFormat:"tile",
defaultItemLayout: "vertical",
defaultItemType: "video",
menuLabel: "diva_other_camera",
behaviour: "multiview",
items: [
{
itemId: "12345678",
title: "France vs Croatia",
caption: "France vs Croatia",
imageUrl: "http://sw.image/img1.jpg",
},
{
itemId: "12345679"
title: "France vs Croatia",
caption: "France vs Croatia - Tactical View",
imageUrl: "http://sw.image/img2.jpg",
},
{
itemId: "12345680"
title: "Star Wars EP III - Revenge Of The Sith",
caption: "I have brought peace, freedom, justice and security to my new Empire!",
imageUrl: "http://sw.image/ep3.jpg",
ccBadge: false,
adBadge: false,
}
]
},
];
vd.behavior = {
endOfPlay: {
countdownToAutoplay: 10000
}
}
return vd;
}
};
return (
<DivaWebBoAdapter
{
...props
}
/>
);
}
export default App;
Instantiate DIVA Player with active multiview mode​
Enrich the Basic instantiation code with
videoId
: It's a string array of up to 4 videoIds to display in multiview mode.multiviewMode
: Optionally added into theconfig
parameter,multiviewMode
's value ismultiview
by default, so even if not set, the videos are shown in side-by-side or in a grid layout, depending on the number of videoIds present in the videoId array. When 'videoIds` contains more than 4 elements, only the first 4 ones are processed. Instead, if themultiviewMode
's value ispip
only two videos are shown in a Picture-in-Picture layout.mediaLists
: Added into thevideoMetadataMap
function, it is not needed if there is a videoIds array.
Working sample code (.tsx)​
The following example instantiates DIVA Player with more than one video in multiview mode.
import React from "react";
import { DivaWebBoAdapter } from "@deltatre-vxp/diva-sdk/diva-web-bo-adapter";
import "@deltatre-vxp/diva-sdk/diva-web-sdk/index.min.css";
const videoIds = ["<videoId1>","<videoId2>","<videoId3>","<videoId4>"];
const 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.11.2/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: videoIds,
libs: libs,
multiviewMode: "multiview"
};
const props = {
settingsUrl: "<Settings URL>",
languageCode: "en-US",
languageDictionary: "en-US",
onDivaBoAdapterError: console.error,
config: config
}
function App() {
const [isVideoLive, setIsVideoLive] = useState(false);
const props: BoAdapterWebComponentProps = {
settingsUrl: "<settings URL>",
languageCode: "en-US",
languageDictionary: "en-US",
onDivaBoAdapterError: console.error,
config: config,
videoMetadataMap: async (vd: VideoMetadata) => {
vd.behavior = {
endOfPlay: {
countdownToAutoplay: 10000
}
}
return vd;
}
};
return (
<DivaWebBoAdapter
{
...props
}
/>
);
}
export default App;
Behaviour​
Activation & Layout​
- The Multi View mode button allows users to select up to three additional videos to stream simultaneously.
- When selecting additional videos in Multi View mode, they start muted.
- Users can close additional videos. The user interface adapts accordingly.
- Users cannot close the video from which the Multi View mode was activated.
- Additional videos inherit audio, closed captions, and HDR settings from the video from which the Multi View mode was activated.
Audio Control​
- Users can choose which video plays audio. Selecting a video automatically mutes the others and marks it as "active."
- The active video displays a sound icon, while the sound icons on the other videos fade out along with the rest of the UI.
Exiting from Multi View mode​
- Upon exiting Multi View, a confirmation dialog double-checks the user's intent.
- If confirmed, the Multi View closes and the primary video returns to the standard DIVA interface.
- If canceled, the Multi View remains as it is.
End of Video:​
- If a video ends, its thumbnail (from video metadata) and a label "The stream has ended" appear. This label is customizable via a dictionary.
List of videos to add to the Multi View:​
- When selecting the Multi View mode button, the list of available videos to stream is displayed.
- The primary video's videomeatadata determines the list of available videos to stream.
Controls:​
- -10s, Play/Pause, +10s
- "Go Live" button
- Subtitles button (except on smartphones)
- Audio track button (except on smartphones)
- Mute/Unmute button
- The control list ensures that non-active video UI fades out as usual.
Platform-Specific Limitations:​
- Web Mobile: Limited to two videos if the screen width is less than 1000px.
Feature Restrictions:​
- No goal alerts are raised.
- "Live Like" is disabled.
- Skip interval is disabled.
- The Multi View button is unavailable in Chromecast and Highlights.
Dictionary​
Ensure the dictionary file contains the relevant keys.
Analytics events​
Find here the available analytics events for multiview.
Migration procedure​
Key Changes​
- In the
videometadata
, the formervideolists
node becomes an array ofmedialists
. Eachvideolist
is transformed into amediaList
object. - What was previously the
channel
node in the formervideolist
's XML, which was referenced in thefeedUrl
field, is now represented as amediaList
object. - What was previously an
item
within thechannel
node in the formervideolist
's XML, which was referenced in thefeedUrl
field, is now represented as amediaListItem
object.
Migration Mapping​
From "videoLists" to Media List
Old Field | New Field |
---|---|
videoLists | mediaLists |
From "videoLists" item to Media List
Old Field | New Field |
---|---|
id | listId (must be generated if empty) |
feedUrl | not needed anymore |
highlightColor | not needed anymore |
highlightColorLight | not needed anymore |
message | rowTitle |
messageNoVideo | noItemsMessage |
menu | menuLabel |
behaviour | behaviour |
pollingInterval | pollingInterval backward compatibility only* |
redirectOnClick | redirectOnClick backward compatibility only* |
isRecommended | isRecommended backward compatibility only* |
template | not needed anymore |
*backward compatibility only: these fields are not used in the new format but are kept for backward compatibility.
- | New Field |
---|---|
- | defaultItemType = "video" |
- | defaultItemLayout = "vertical" |
- | showInEndOfPlay = false* |
*showInEndOfPlay
: if "true" it will add the current list in the End Of Play experience.
From XML feed "items" to Media List Items
Old Field | New Field |
---|---|
id | itemId |
title | title |
description | caption |
videoThumbnail | imageUrl |
link | not needed anymore |
guid | not needed anymore |
pubDate | not needed anymore |
category | not needed anymore |
videoImage | not needed anymore |
cameraType | not needed anymore |
cameras | not needed anymore |
- | New Field |
---|---|
- | imageFormat = "tile" |
- | itemType = "video" |
- | itemLayout = "vertical" |
Example: Transformation Process​
Input - Original Video Metadata JSON (Old Format)
{
"videoLists": [
{
"feedUrl": "https://example.com/feed.xml",
"highlightColor": "#FF0000",
"highlightColorLight": "#FF0000",
"message": "Recommended Videos",
"messageNoVideo": "No videos available",
"menu": "Recommended",
"behaviour": "multiview",
"pollingInterval": 30000,
"redirectOnClick": true,
"isRecommended": true,
"template": "default"
}
]
}
Input - Original Video list RSS Feed XML (Old Format)
<rss version="2.0">
<script src="chrome-extension://mfidniedemcgceagapgdekdbmanojomk/js/elephant.js"/>
<channel>
<title>Star Cricket RSS Channel</title>
<link>https://www.starsports.com/sitemaps/news.xml</link>
<description>Latest News</description>
<language>en-gb</language>
<lastBuildDate>2014-04-04T07:56:00Z</lastBuildDate>
<copyright>Copyright (C) Star Cricket</copyright>
<item>
<id>live_videolist</id>
<title>4. Bra Vs Ger - Live</title>
<description>Live hls-v3 with ProgrmamDateTime shifted 20 min after</description>
<link>custom-link</link>
<guid isPermaLink="false"/>
<pubDate>2014-06-11T22:25:51Z</pubDate>
<videoImage url=""/>
<videoThumbnail url="my-image.png"/>
<live>true</live>
<label>live</label>
<category>video</category>
<cameraType>MULTICAM</cameraType>
<cameras>TEAMB</cameras>
</item>
</channel>
</rss>
Output - Converted Media List Format (New Format)
{
"mediaLists": [
{
"listId": "mediaListId",
"rowTitle": "Recommended Videos",
"noItemsMessage": "No videos available",
"menuLabel": "Recommended",
"behaviour": "multiview",
"pollingInterval": 30000,
"redirectOnClick": true,
"isRecommended": true,
"defaultItemType": "video",
"defaultItemLayout": "vertical",
"defaulImageFormat": "tile",
"items": [
{
"itemId": "live_videolist",
"title": "4. Bra Vs Ger - Live",
"caption": "Live hls-v3 with Program DateTime shifted 20 min after",
"imageUrl": "my-image.png",
"itemType": "video",
"itemLayout": "vertical"
}
]
}
]
}