#4: Building a Virtual Timeline (schedule)

Now that your Sources are defined, that you have a good idea of the Audiences segmentation, and that your Virtual Channel Service(s) is created, you are set to schedule programs on your Virtual Channel.

Define a channel start-time

By default, when creating a Virtual Channel service, the manifest delivered by broadpeak.io for this service, references the original content defined when the Service was created, until a program is scheduled. From there, any program can be scheduled in the future. The first program defines the beginning on your Virtual Timeline, this is your T0.

In some cases, you may not need to schedule content on a specific period of the day/night, while you still want the channel to be available in the EPG. It is perfectly fine not to schedule any program on the service, broadpeak.io will reference the original content defined at Service creation in the manifest when no programs are scheduled.

📘

Note

Commercially, your consumption will be counted as soon as the Virtual Channel Service is created. The time where no programs are scheduled on the channel is still considered as using the Service, and you will be charged for it.

Virtual Channel

If you don't intend to enable personalization per Audience in your service, and that you have skipped step 3, then this section is for you. If instead, you intend to use some personalization per Audience, you can go to the next chapter.

Scheduling

Program scheduling is achieved through the use of the broadpeak.io API, which can be found here. To better understand the concept of scheduling on broadpeak.io we invite you to check the Key concepts section.

Scheduling a Program

To schedule a VOD, or Live event program you must send a content replacement API Call as defined here (REST)

The mandatory information which needs to be provided using the REST API is as follows:

  • serviceId: this is the Id of the Virtual Channel service that you have created.
  • name: you must choose a name for your blackout slot.
  • start-time: the time you want the program to start. For the first program, this is your T0.
  • replacement: you must provide the Id of the broadpeak.io Source of the content you want to program, as an object.
  • duration: you must provide the duration of the program. It should be the duration of the VOD or Live event or if you don't want to schedule the whole asset, the duration time it should be displayed on the screen.

As a result the program will be scheduled at the defined start-time, for the provided duration.

Scheduling consecutive Programs

To build a full Virtual Channel, Programs must be scheduled consecutively. A content replacement slot must be created for each program to schedule, and timing shall be computed accordingly.

The logic is simple: the start-time of the next program is the sum of the start-time and the duration of the previous program. So to schedule three programs consecutively on a Virtual Channel service which Id is 10, from 2am, I would have to send the three following calls:

Sources:
VOD1:

  • broadpeak.io id: 1001
  • duration: 1800 seconds

VOD2

  • broadpeak.io id: 1002
  • duration: 3600 seconds

VOD3

  • broadpeak.io id: 1003
  • duration: 7200 seconds

Virtual Timeline:

Content replacement API calls:
Call 1:

  • serviceId: 10
  • name: program_vod_1
  • start-time: 2022-06-06T02:00:00Z
  • replacement: { id: 1001 }
  • duration: 1800
curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1001
     },
     "startTime": "2022-06-06T02:00:00Z",
     "name": "program_vod_1",
     "duration": 1800
}
'

Call 2:

  • serviceId: 10
  • name: program_vod_2
  • start-time: 2022-06-06T02:00:00Z + 1800 seconds = 2022-06-06T02:30:00Z
  • replacement: { id: 1002 }
  • duration: 3600
curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": "1002"
     },
     "startTime": "2022-06-06T02:30:00Z",
     "name": "program_vod_2",
     "duration": 3600
}
'

Call 3:

  • serviceId: 10
  • name: program_vod_3
  • start-time: 2022-06-06T02:30:00Z + 3600 = 2022-06-06T03:30:00Z
  • replacement: { id: 1003 }
  • duration: 7200
curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1003
     },
     "startTime": "2022-06-06T03:30:00Z",
     "name": "program_vod_3",
     "duration": 7200
}
'
Updating your schedule

In the event you need to make some change on the program scheduled, it is possible to update an existing content replacement slot to update some of the parameters such as the Source and the duration. This could be the case for sport content where sometimes games run overtime. The API documentation to update an existing slot is available here (REST) or here (ESNI).

🚧

Extending or shortening a scheduled program

Updating a program by extending or reducing the duration of the content-replacement might have an impact on your schedule. In fact, to ensure the best quality of experience, if one program is being shortened or extended, all the following programs must be updated as their start-time will most likely change as well. Don't forget to update the whole Virtual Timeline!

Personalized Virtual Channel

Scheduling

Channels can be personalized per Audience. To implement personalized Virtual Channels, the logic is the same, but slots must contain information about the Audience it targets.

For the sake of simplicity, we will take an example where TV Subscribers are split into three groups, Seniors, Adults, and young Adults. We have previously create these categories on broadpeak.io (see previous article (https://developers.broadpeak.io/docs/virtual-channel-3-enabling-personalization))

  • Seniors category ID : 1
  • Adults category ID : 2
  • Young Adults category ID : 3

From there, we will want to create three variants on the Virtual Service Id 10, with some programs being common to the three Audiences, and others that are specific to each Audience. We will assume for this example that the Virtual Timeline is as below:

VOD 2 and VOD 4 are programs that are being scheduled regardless of the Audience, so everyone will experience it at the same time, for the same duration.

For Variant 1 which represents the Seniors (category ID = 1), we need to send three content replacement calls for VOD1, VOD3, and LIVE1:

Call 1

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1001
     },
     "category": {
          "id": 1
     },
     "startTime": "2022-06-06T02:00:00Z",
     "name": "program_vod_1",
     "duration": 1800,
     "categoryName": "Seniors"
}

Call 2

curl --request POST \
     --url https://api.broadpeak.io/v1/services/blackout/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1002
     },
     "category": {
          "id": 1
     },
     "startTime": "2022-06-06T03:30:00Z",
     "name": "program_vod_2",
     "duration": 3000,
     "categoryName": "Seniors"
}

Call 3

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1003
     },
     "category": {
          "id": 1
     },
     "startTime": "2022-06-06T05:20:00Z",
     "name": "program_vod_3",
     "duration": 1800,
     "categoryName": "Seniors"
}

For Variant 2 which represent the Adults (category ID = 2), we need to send four content replacement calls for LIVE21, VOD22, VOD23 and VOD24.
Call 1 :

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 0021
     },
     "category": {
          "id": 2
     },
     "startTime": "2022-06-06T02:00:00Z",
     "name": "program_vod_21",
     "duration": 1800,
     "categoryName": "Adults"
}

Call 2 :

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1022
     },
    "category": {
          "id": 2
     },
     "startTime": "2022-06-06T03:30:00Z",
     "name": "program_vod_22",
     "duration": 1500,
     "categoryName": "Adults"
}

Call 3 :

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 0023
     },
     "category": {
          "id": 2
     },
     "startTime": "2022-06-06T03:55:00Z",
     "name": "program_vod_23",
     "duration": 1500,
     "categoryName": "Adults"
}

Call 4 :

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 0024
     },
     "category": {
          "id": 2
     },
     "startTime": "2022-06-06T05:20:00Z",
     "name": "program_vod_24",
     "duration": 2000,
     "categoryName": "Adults"
}

For Variant 3, which represents the Young Adults (category ID = 3), we need to send three content replacement calls for VOD31, VOD32 and VOD 33.
Call 1

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1031
     },
     "category": {
          "id": 3
     },
     "startTime": "2022-06-06T02:00:00Z",
     "name": "program_vod_31",
     "duration": 1800,
     "categoryName": "YoungAdults"
}

Call 2

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1032
     },
     "category": {
          "id": 3
     },
     "startTime": "2022-06-06T03:30:00Z",
     "name": "program_vod_32",
     "duration": 3600,
     "categoryName": "YoungAdults"
}

Call 3

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1033
     },
     "category": {
          "id": 3
     },
     "startTime": "2022-06-06T05:20:00Z",
     "name": "program_vod_33",
     "duration": 1500,
     "categoryName": "YoungAdults"
}

Since both VOD 2 and VOD4 should be scheduled at the same time for all Audiences, we will create two unconditional slots.

Call 1:

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1002
     },
     "startTime": "2022-06-06T02:30:00Z",
     "name": "program_vod_2_unconditional",
     "duration": 3600,
}
'

Call 2:

curl --request POST \
     --url https://api.broadpeak.io/v1/services/virtual-channel/10/slots \
     --header 'Accept: application/json' \
     --header 'Authorization: Bearer XXXX' \
     --header 'Content-Type: application/json' \
     --data '
{
     "replacement": {
          "id": 1004
     },
     "startTime": "2022-06-06T04:20:00Z",
     "name": "program_vod_4_unconditional",
     "duration": 3600,
}
'

📘

Enabling DASH and HLS on your Virtual Channel

In broadpeak.io, a Virtual Channel only delivers a single format, DASH or HLS. When the need to use both formats raises, two different Virtual Channel Services need to be created. All Slots created on the DASH Service, must also be created on the HLS Service. The example above only shows the API call that would be sent to either a DASH or an HLS Service.