Skip to main content

Chain play / Up Next

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 up-next in combination with end of play.

Before starting​

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.

Up next configuration​

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

  • undefined default value if not set and up next not shown
  • This is the only mandatory value to set to show up next:
{ videoId: "<videoId>" } // 
  • These are the complete fields that can be set:
{
videoId: "<videoId>",
title: "<title>",
caption: "<caption>",
imageUrl: "<imageUrl>",
}

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.upNext = {
videoId: "500080_minimal",
title: "Juventus vs Inter",
caption: "Final match of the season",
imageUrl: "https://www.example.com/image.jpg",
};
vd.behavior = {
endOfPlay: {
countdownToAutoplay: 10000
}
}
return vd;
}
}

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

Override the Up Next component​

To override the Up Next component, you can use the ChainPlayComponent property in the renderCustomization object. This property allows you to pass a custom component to the Up Next screen.

const config = {
// ...other configuration
renderCustomization: {
ChainPlayComponent: 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 in activeElement 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 Chain play / Up Next.

Behaviour​

  • During the end screen, ChainPlay elements will be shown on the bottom left, including Next Episode Information and countdown to autoplay.
  • When casting to Chromecast, ChainPlay is disabled on the receiver device, meaning the next episode prompt and countdown will not be shown on the receiver.

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 next episode 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 next episode 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.

Countdown to Up-Next​

  • When the countdown finishes without user interaction, the next episode will automatically load using the supplied video ID and begin playback.
  • When the user selects the "Next Episode" item by clicking or tapping on it, the next episode will launch immediately, overriding the countdown.

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.