Picture in picture (PiP)
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 smaller floating video on top of another screen when switching apps or navigating away from a video.

- The icon displayed for this action is a small camera in a bigger video (fixed and cannot be changed).
- The icon color can be customized and the label could be defined in the mediaLists data as
menuLabel
.
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 PiP view.
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
ispip
. - 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.
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,
multiviewMode: "pip"
};
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_in_pip",
defaulImageFormat:"tile",
defaultItemLayout: "vertical",
defaultItemType: "video",
menuLabel: "diva_pip",
behaviour: "pip",
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",
}
]
},
];
vd.behavior = {
endOfPlay: {
countdownToAutoplay: 10000
}
}
return vd;
}
}
return (
<DivaWebBoAdapter
{
...props
}
/>
);
}
export default App;
Start the Diva player in multiview mode with PiP​
Enrich the Basic instantiation code with
videoId
It's a string array of up to 2 videoIds to display in multiview PiP mode.multiviewMode
added into theconfig
parameter.multiviewMode
must valuepip
.mediaLists
added into thevideoMetadataMap
function is not needed if there is a videoIds array.
When 'videoIds` contains more than 2 elements, only the first 2 ones are processed and shown in a Picture-in-Picture layout.
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 videoIds = ["<videoId1>","<videoId2>"];
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: "pip"
};
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;
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": "multistreamPip",
"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": "multistreamPip",
"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"
}
]
}
]
}