Add a splash screen to live streams and cloud recordings with Daily’s VCS baseline composition

If you’ve been following our recent announcements, you’ll know Daily now offers a new tool for customizing Daily videos being live streamed or recorded: the Video Component System (VCS).

VCS is our video-oriented layout engine that can be used to create layouts (or "compositions"), which turn Daily WebRTC calls into highly customized interactive live streams or recorded content.

There are a couple options for how to use VCS. We’ll start with the easier option to use:

  • The baseline composition, which is a sub-category of the larger VCS SDK made available through daily-js and react-native-daily-js. It is a collection of layouts and graphical features that can be accessed through the live streaming and recording methods for daily-js or react-native-daily-js. In essence, it includes default configurations for the VCS SDK which allows developers to get most of the customization benefits of using VCS by just passing JSON-based options via the Daily library they’re already using for video calls.
  • The VCS SDK: This creates even more customization options for developers, who can build their own components with the SDK directly. It requires more coding on the development side, but provides more control to developers in terms of what your live stream or cloud recording looks like in the end.

In other words, the VCS SDK is the open-sourced version of our baseline composition for daily-js or react-native-daily-js. This means if there’s anything you can do with the baseline composition, you could also build it yourself with the VCS SDK.

See our recent moving watermark tutorial, which shows how to build custom components with the VCS SDK.


Today’s agenda

In today’s tutorial, we’ll look at how to:

  • Show a splash screen at the start of a live stream
  • Show a splash screen during a live stream
  • Show a splash screen with a custom image as the background

This tutorial can be tested using the Daily Prebuilt demo app, though we won’t focus on the demo app code today. Instead, we’ll specifically look at which composition parameters should be used to create a splash screen.

If you want to test these settings with a real live stream, you can run the demo app locally using the instructions included in a previous VCS tutorial.


What are composition parameters?

Daily’s baseline composition accepts an extensive list of options (or parameters) to customize layout and graphical features such as:

  • overlay text and how it’s styled
  • image overlays and how they’re styled
  • toast components and how they’re styled
  • title slates (a.k.a splash screens) and how they’re styled
  • participant labels and (you guessed it!) how they’re styled

To quickly test all the different composition parameters, check out the VCS Simulator, which lets you toggle different settings, as well as track the settings you’re using in the API Call Builder side panel.

VCS Simulator with the API Call Builder pointed out on the right side

To track the settings being used, you can click the “Record” button in the API Call Builder tab and then update any of the composition parameters you’d like to use. You’ll notice relevant composition parameters (composition_params) being added to the layout options in the Daily instance method being used (startRecording() is the default).

This means that you can copy the composition_params from the API Call Builder once you’re happy with your layout and use the options directly in your code to know exactly what your video feed will look like ahead of time.


How to pass options for the baseline composition

The Daily baseline composition allows you to pass composition parameters and assets (i.e. images) of your choice when you start a live stream or recording. These are set under the composition_params and session_assets options, like so:

await callFrame.startLiveStreaming({
  rtmpUrl: “rtmp://RTMP_ENDPOINT/STREAM_KEY”,
  layout: {
    preset: 'custom',
    composition_id: 'daily:baseline', // optional (default value)
    composition_params: {
       // We’ll add these parameters shortly
   },
    session_assets: {
      // the key can be any string
      // the value must be an absolute URL to a hosted .png asset
      'images/background: 'https://example.com/foobar.png',
    },
  },
});

Note: callFrame is the instance of the DailyIframe in your app.

Before moving on, let’s also review a few requirements in this block of code that apply with any baseline composition usage:

  • You must set layout.preset to custom to access the baseline composition when you start a live stream (or recording). You can't switch to using the baseline composition after the live stream is started.
  • The composition_id can be added but you don’t have to for the baseline composition since 'daily:baseline' is the default value.
  • session_assets must be included when you start the live stream (or cloud recording), even if you’re not using the assets until later in the call.
  • session_assets images must use the .png file format and point to an absolute URL.

Creating a splash screen (or “title slate”)

There are a couple types of splash screens you can add with the baseline composition. We'll call them "title slates" going forward, though, to match the language used in the API.

  • “Auto” opening slates that show as soon as the live stream or recording starts, via the enableAutoOpeningSlate option
  • General title slates that can be shown any time in the live streaming or recording, via the showTitleSlate options.

Let’s look at the first option: opening slates. We can quickly test this in the simulator.

await callFrame.startLiveStreaming({
  rtmpUrl: “rtmp://RTMP_ENDPOINT/STREAM_KEY”,
  layout: {
    preset: "custom",
    composition_params: {
      "enableAutoOpeningSlate": true,
      "openingSlate.duration_secs": 2,
      "openingSlate.title": "Hello!!",
      "openingSlate.fontWeight": "900",
      "openingSlate.fontStyle": "italic",
      "openingSlate.subtitle": "Bill & Ted: Bogus Journey is better than Excellent Adventure",
      "showTitleSlate": false
    },
});

Here, we start our live stream with the Daily startLiveStreaming() method. Under composition_params, we set enableAutoOpeningSlate to true so it shows when the live stream starts. The other options are extra styles you can add to spruce it up.

Here’s how this will look:

A live stream starting with the opening title slate displayed.

It's as simple as including these options in your startLiveStreaming() method call.

Let’s say you want to transition different segments of your live stream with a splash screen, though. We need to use a regular title slate in this case that we can show anytime during the live stream. To do this, we’ll use the showTitleSlate option to toggle the slate's appearance in the stream.

A live stream feed that has already started transitioning to a title slate.

The code for this looks pretty similar to our previous example:

await callFrame.updateLiveStreaming({
  layout: {
    preset: "custom",
    composition_params: {
      "showTitleSlate": true,
      "titleSlate.title": "Another hot take",
      "titleSlate.subtitle": "Adam Sandler is better in dramas than comedies",
      "titleSlate.bgColor": "rgba(220, 100, 70, 1)",
      "titleSlate.fontFamily": "Exo"
    }
  }
});

One thing to keep in mind with these types of title slates is that they don’t auto-clear. You need to call updateLiveStreaming() once to show it with { "showTitleSlate": true}, and a second time to clear it with { "showTitleSlate": false}.

Creating our splash screen with an image as a background

As mentioned earlier, the Daily baseline composition allows you to pass images of your choice when you start a live stream or recording under the session_assets option, like so:

await callFrame.startLiveStreaming({
  rtmpUrl: “rtmp://RTMP_ENDPOINT/STREAM_KEY”,
  layout: {
    preset: 'custom',
    composition_id: 'daily:baseline', // optional (default value)
    composition_params: {
       // We’ll add these parameters shortly
   },
    session_assets: {
      // the key can be any string
      // the value must be an absolute URL to a hosted .png asset
      'images/background: 'https://example.com/foobar.png',
    },
  },
});

Let’s pick a image we want to show as our background image now:

Screenshot from Bill and Ted's Bogus Journey

To add our background image as a session asset, we need to provide it when the live stream is started:

 await callFrame.startLiveStreaming({
  rtmpUrl: “rtmp://RTMP_ENDPOINT/STREAM_KEY”,
  layout: {
    preset: "custom",
    composition_params: {
 	},
    session_assets: {
   		“images/background”: “https://www.daily.co/blog/content/images/size/w1600/2022/07/billandted.png”,
  	}
});

Then, when we’re ready to use it, we can show our title slate with the image background like so:

await callFrame.updateLiveStreaming({
  layout: {
    preset: "custom",
    composition_params: {
      // sets the background image
      "titleSlate.bgImageAssetName": "background",
      "titleSlate.bgColor": "rgba(0, 0, 0, 1)",
      "titleSlate.fontWeight": "600",
      "titleSlate.textColor": "rgba(255, 255, 255, 1)",
      "titleSlate.fontSize_gu": 2.9,
      "titleSlate.fontFamily": "Roboto",
      "showTitleSlate": false
    }
  }
});

We specify the background image with the "titleSlate.bgImageAssetName" option and use the image name that was set in session_assets (“background’). This means you could provide multiple images and set a different background image for different title slates.

Testing it in the VCS Simulator, it looks like this:

Live stream transitioning to a splash screen with an image background.

And there you have it! Title slates (or splash screens) three ways.


Wrapping up

We hope this tutorial helps get the creative juices flowing for all the ways you can customize your live stream and recording video feed layouts and appearance.

Be sure to review our VCS guide for additional information on using the baseline composition, as well as our previous blog posts on the topic:

If you would prefer to write your own VCS components, check out our docs for the VCS SDK and tutorial post.

Never miss a story

Get the latest direct to your inbox.