Recommendations / Related
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, at the end, the activation of Recommendations in combination with end of play.
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 related property.
- Ensure the VideoMetadata contains the countdownToAutoplay property.
- Ensure the settings contains the timeToDisableAutoplay property.
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.
There are 2 ways to populate the Recommended content: VideoLists and Related.
Recommendations by Video lists​
See videoLists.
Recommendations by Related​
Write the App() function to read the VideoMetadataMap as in the following example, and set the related
property:
undefined
default value if not set and recommendations not shown- This is the only mandatory value to set to show recommendations:
items: [
{
itemId: "<videoId>",
}
]
- These are the complete fields that can be set:
rowTitle: "<rowTitle>", // if empty, the default will be: diva_eop_recommendation_title
imageFormat: "<imageFormat>", // "tile"
items: [
{
itemId: "<videoId>",
title: "<title>",
caption: "<caption>",
imageUrl: "<imageUrl>",
ccBadge: "<ccBadge>", //true or false, TV only
adBadge: "<adBadge>", //true or false, TV only
}
]
Customize the click behaviour​
The default behaviour once we click on the item is switch
(play the clicked video).Â
If the integrators need to override the click behaviour they can set the callback on Diva config by adding:
config.onRelatedClick = (itemId: string): boolean => {
// custom logic
return false; // false means the default behaviour (switch) will be executed. On WebTV, the default behaviour is never executed.
}
Autoplay​
Write the App() function to read the VideoMetadataMap as in the following example, and set the endOfPlay
properties:
"behaviour": {
"endOfPlay": {
"countdownToAutoplay":10000 //milliseconds, default 10000, 0 or negative means disabled
},
},
In the settings
file, the general
section must contain "timeToDisableAutoplay": 5400000
, like in the following example:
{
"general": {
"timeToDisableAutoplay": 5400000, //milliseconds, default 0, 0 or negative means disabled
},
}
The autoplay will start if countdownToAutoplay
has set. In this case the countdown will start.
countdownToAutoplay
will enable or disable the autoplay at the end of the milliseconds set ()timeToDisableAutoplay
will disable the autoplay at the end of the milliseconds set with no interactions
Working sample code (.tsx)​
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://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,
settings: {
general: {
timeToDisableAutoplay: 5400000
}
}
};
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.related = {
rowTitle: "diva_eop_related_title",
imageFormat: "tile",
items: [{
itemId: "12345678"
title: "Star Wars EP I - The Phantom Menace",
caption: "Mesa Jar Jar Binks",
imageUrl: "http://sw.image/ep1.jpg",
ccBadge: false,
adBadge: false,
},{
itemId: "12345679"
title: "Star Wars EP II - Attack Of The Clones",
caption: "I don't like sand. It's coarse and rough and irritating and it gets everywhere",
imageUrl: "http://sw.image/ep2.jpg",
ccBadge: false,
adBadge: false,
},{
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} />
</>
);
}
Override the Recommendations/Related component​
To override the Recommendations/Related component, you can use the ChainPlayComponent
property in the renderCustomization
object.
This property allows you to pass a custom component to the Recommendations/Related screen.
const config = {
// ...other configuration
renderCustomization: {
ChainPlayComponent: (props) => React.ReactElement // CustomChainPlayComponent
},
};
Props​
There are several props provided by Diva and passed to your component that may be useful for you.
type Props = {
/**
* The metadata of the video that is currently playing/ending.
*/
videoMetadata: VideoMetadata | undefined;
/**
* Function to switch the video to the next one.
* @param videoId The ID of the video to switch to.
*/
switchVideo: (videoId: string) => void;
/**
* Information whether the component should be focused. Default: false
* Passed only on webtv platforms.
*/
focused?: boolean;
};
Focus Handling on WebTV platforms​
The component should not focus itself on render. Rather, the focus should be
based on the focused
prop.
- When this prop becomes
true
, the component should focus itself visually and make sure that it will be able to receive keydown events. - When this prop becomes
false
, the component should only remove visual focus representation and make sure not to react to any events. Any change inactiveElement
will be handled by Diva.
Events handling​
If the component handles keydown events, it should stop the propagation of the event if the event was handled by the component. Events that do not result in any action by the component should be propagated to Diva. This allows handling the focus back to Diva in case of direction keys not being processed by the component.
Dynamic fallback to default component​
It is possible to fallback back to the default component provided by Diva
dynamically from your custom component. To do this, simply throw
CustomComponentRenderDefault
error during the render phase.
import { CustomComponentRenderDefault } from '@deltatre-vxp/diva-webtv-sdk';
const MyCustomComponent = ({ focused }: Props) => {
const [dataError, setDataError] = useState(false);
useEffect(() => {
(async () => {
try {
// Fetch data
} catch (error) {
setDataError(true);
}
})();
}, [])
if (dataError) {
throw new CustomComponentRenderDefault();
}
return (
// Your component
)
};
Empty render​
Sometimes you might wish not to render anything. In such case, it is not
possible to just return null
. The null render result is not detectable easily
by the parent component. Because of focus handling, Diva would still try to
focus this empty component. To avoid this, you can throw
CustomComponentRenderNothing
error. This will be handled by Diva, nothing will
be rendered and the focus will not be sent to the component.
import { CustomComponentRenderNothing } from '@deltatre-vxp/diva-webtv-sdk';
const MyCustomComponent = ({ focused }: Props) => {
const data = useDataProvider();
if (data.length === 0) {
throw new CustomComponentRenderNothing();
}
return (
// Your component
)
};
Error handling​
Your custom component is wrapped by ErrorBoundary. If an error is thrown during
the render phase, the component will be unmounted and the default component will
be rendered instead. The error will be logged. In case of
CustomComponentRenderDefault
or CustomComponentRenderNothing
error, the
errors are not logged as errors.
In development mode, the error message will always be displayed and it may trigger error overlays for dev servers. However, in production mode these errors should be handled gracefully without interrupting the user experience.
Dictionary​
Ensure the dictionary file contains the relevant keys.
Analytics events​
Find here the available analytics events for the Recommendations / Related.
Behaviour​
- During the end screen, Recommendations elements will be shown at the bottom of the screen, including countdown to autoplay on the first item.
- For entertainment content, only one row of recommendations should be shown on the screen.
- If both Up Next and Recommendations are available, Up Next will take priority.
Countdown Activation​
- The countdown starts only when the Squeeze Back feature is triggered or at the end of playback (if Squeeze Back is not enabled).
- The countdown timer will display the remaining seconds as per the design specifications. If no countdown value is set, the timer will not appear.
- When the countdown finishes, the first video item will automatically start unless the user interacts with the Endboard.
Countdown Cancellation​
- If the user interacts with the Endboard, the countdown timer is canceled, and the automatic transition to the first video is halted. The specific interactions that cancel the countdown vary by platform:
- WebTV: Any change in focus, or pressing any directional key, even if it does not result in a focus shift.
- Responsive Web: Any mouse movement will cancel the countdown.
Interaction with Recommendations​
- In the recommendation row, when a user clicks on an item, the system should provide two possible actions:
- Start video directly: This is the default behavior.
- Enable a callback: This allows the integrator to override the default behavior if necessary. The callback will be configurable and should trigger when the item is selected, instead of directly starting the video.
Autoplay Limitations​
- To prevent continuous autoplay during inactive sessions, a ChainPlay timeout will be applied:
- The system will pause autoplay after a set number of episodes (set by the platform or session) if there is no user interaction.
- A session-based timer will track user inactivity. If the user does not interact with the device for a specified period, autoplay will be paused.
- Any user interaction with the device (e.g., pressing buttons, moving the cursor, or tapping on the screen) will reset the inactivity timer, allowing autoplay to continue.