Live API: Cue Points and Ad Beacons with SSAI

Product(s)
Video Cloud
Live
Brightcove Player
SSAI
Role(s)
API Developer
Topic(s)
Live Streaming
SSAI
API(s)
Live API

In this topic, you will learn how to manage cue points and ad beacons when using Brightcove's Server-Side Ad Insertion (SSAI) for your live stream jobs.

Overview

Server-side ad insertion (SSAI) allows you display ads during a live streaming event at specified times. For general information, see the Live API: Server-Side Ad Insertion (SSAI) document.

Cue points

Ad breaks are triggered by cue points, which can be specified in two ways:

  • Sent to Brightcove by the encoder
  • Immediate cue points created via the Live API

From the encoder

The Brightcove live delivery system can interpret cue points submitted by the encoder in the AMF format:

AMFDataList
[0]:onCuePoint
[1]:{Obj[]:
  time: 1.9889, //Difference from PTS of THIS packet to the first PTS of the 1st video frame in the adbreak
  name: "scte35",
  type: "event",
  ad_server_data: "YWJjZGVmZ2g=",	// optional introduced by Brightcove. It is a base64 encoded json map of parameters e.g. {‘key’:’value’}
  parameters: {Obj[]:
    type: "avail_in",
    duration: 12.0
  }
}

Notes:

  • Only avail_in type cue points are currently supported.
  • SCTE-35 cue points are supported for both RTMP and TS inputs.

Manual cue point insertion

You can create immediate cue points using the Live API by sending a POST request:

Method POST
URL https://api.bcovlive.io/v1/jobs/Job_ID/cuepoint
Header X-API-KEY: your API KEY

Include a request body specifying the following:

Field Type Description
duration Integer Duration of the break in seconds.

The duration of the cue point being inserted needs to be at least twice the length of the segments in the job. See the duration example.
timecode SMPTE format OPTIONAL: A timecode in SMPTE format, HH:MM:SS:FF (FF = frames), to specify when a set of any variables (key/value pairs) should be passed to the adServer.

If omitted, the cue point will be inserted immediately.

If you use the timecode property, the encoder must be sending SMPTE-formatted (HH:MM:SS:FF) timecode stored in the tc property via OnFI. Timecodes are from the start of the live stream.
ad_server_data Object OPTIONAL: The key/value pairs you pass will depend on the ad server you are using. For more details, see your ad server documentation and the Targeting ads using ad macros section.

Duration example

The duration of the cue point being inserted needs to be at least twice the length of the segments in the job.

For example, inserting a 10 second cue point in a job with "segment_seconds"=4, will work fine. However, inserting the same cue point in a job with "segment_seconds"=6 will result in the following error:

"error": "The parameter duration should be greater than
  or equal to (2 * target duration) of the job"
 

Sample request body

{
  "duration": 30,
  "timecode": "15:50:49:16",
  "ad_server_data" : {
  "adbreakid": 12312
  "breaktheme": "fitness"
  }
}

Notes

  1. Software encoders such as Wirecast and OBS do not support the sending timecode via OnFI packets in the RTMP stream
  2. Elemental hardware encoders do support the sending timecode via OnFI packets in the RTMP stream

Sample response

{
  "id": "Job_ID",
  "cue_point": {
    "id": "adBreak-2f58393ada1442d98eca0817fa565ba4",
    "duration": 30,
    "accuracy": "segment", [Can be segment or frame  ]
    "inserted_at": "2017-07-21T09:30:46.307Z" [ Time when the cue point was inserted in the stream]
  },
}

Beacons

Beacons are data points on playback sent to third-party analytics to track whether and how much of ads were played. In this section we will look at the beacon types that can be set using the Live API, and variables that can be used to provide the data. The next section will detail the API requests use to create and manage beacon sets.

Beacon types

Beacon Types
Beacon Type Description
Load Fired once per session and only triggered when top level manifest is requested
Play Content has been requested and the first segment returned
Heartbeat Target duration (segment seconds)
AdStart Individual ad started
AdFirstQuartile First ad quartile (25%)
AdMidpoint Second ad quartile (50%)
AdThirdQuartile Third ad quartile (75%)
AdComplete Individual ad completed
AdBreakStart Ad break has started
AdBreakComplete ad break has ended

Valid beacon variables

The table below shows the variables you can use to provide data for the beacon URLs. To include a variable, surround with double curly braces, like this: {{job.job_id}} . See the next section on managing beacon sets for full examples.

Beacon Variables
Variable
Description
session.session_id
unique session id
job.job_id
unique job id
application_ad_configuration.description
description value of the application at session creation
random.int32
random 32-bit signed integer
random.int64
random 64-bit signed integer
random.uint32
random 32-bit unsigned integer
random.uint64
random 64-bit unsigned integer
random.uuid
random uuid
server.timestamputc
epoch time in milliseconds when the call from the ads-api has been made
client.useragene
http user-agent header value at session creation
client.ipaddress
http x-forwarded-for header value at session creation, if provided, otherwise the remote address
client.referrer
http referer header value at session creation (correct spelling)
client.referer
http referer header value at session creation (http spelling)
live.adbreak
(currently unused)
live.adbreakduration
double-precision floating-point value in seconds
live.adbreakdurationint
integer value in seconds

Managing beacon sets

This section provides details on the API requests to manage beacon sets. See the previous section for beacon types and variables.

To add a beacon set to a Live job, first create the beacon set, and then include the id when you create the job, like this:

{
"live_stream": true,
"region": "us-west-2",
"reconnect_time": 30,
"ad_insertion": true,
"beacon_set": "beacon_set_id", ...

Create a beacon set

To create a beacon set, send a POST request:

Method POST
URL https://api.bcovlive.io/v1/ssai/beaconsets
Header X-API-KEY: your API KEY

Sample request body

{
  "account_id": "User's Account ID [Optional]",
  "beacon_urls": [
    {
      "beacon_url": "https://myserver.com/beaconRX/{{job.job_id}}/load?position=load&sid={{session.session_id}}&jid={{job.job_id}}&app={{application_ad_configuration.description}}&rnd32={{random.int32}}&rnd64={{random.int64}}&bid={{random.uuid}}&t={{server.timestamputc}}&ua={{client.useragent}}&ip={{client.ipaddress}}&ref={{client.referrer}}&ref={{client.referer}}&ab={{live.adbreak}}&abd={{live.adbreakduration}}&abdi={{live.adbreakdurationint}}",
      "beacon_type": "Load"
    },
    {
      "beacon_url": "https://myserver.com/beaconRX/{{job.job_id}}/play?position=play&sid={{session.session_id}}&jid={{job.job_id}}&app={{application_ad_configuration.description}}&rnd32={{random.int32}}&rnd64={{random.int64}}&bid={{random.uuid}}&t={{server.timestamputc}}&ua={{client.useragent}}&ip={{client.ipaddress}}&ref={{client.referrer}}&ref={{client.referer}}&ab={{live.adbreak}}&abd={{live.adbreakduration}}&abdi={{live.adbreakdurationint}}",
      "beacon_type": "Play"
    }
  ]
}

Sample response

{
  "beacon_set": {
    "beacon_urls": [{
    "beacon_url": "https://myserver.com/beaconRX/{{job.job_id}}/load?position=load&sid={{session.session_id}}&jid={{job.job_id}}&app={{application_ad_configuration.description}}&rnd32={{random.int32}}&rnd64={{random.int64}}&bid={{random.uuid}}&t={{server.timestamputc}}&ua={{client.useragent}}&ip={{client.ipaddress}}&ref={{client.referrer}}&ref={{client.referer}}&ab={{live.adbreak}}&abd={{live.adbreakduration}}&abdi={{live.adbreakdurationint}}",
    "beacon_type": "Load"
  },
  {
    "beacon_url": "https://myserver.com/beaconRX/{{job.job_id}}/play?position=play&sid={{session.session_id}}&jid={{job.job_id}}&app={{application_ad_configuration.description}}&rnd32={{random.int32}}&rnd64={{random.int64}}&bid={{random.uuid}}&t={{server.timestamputc}}&ua={{client.useragent}}&ip={{client.ipaddress}}&ref={{client.referrer}}&ref={{client.referer}}&ab={{live.adbreak}}&abd={{live.adbreakduration}}&abdi={{live.adbreakdurationint}}",
    "beacon_type": "Play"
  }],
  "beacon_set_id": "Inserted Beacon Set ID",
  "account_id": "USER's ACCOUNT ID"
  }
  "inserted": true
}

Update a beacon set

Updating a beacon set is similar to creating one. Submit a PUT request:

Method PUT
URL https://api.bcovlive.io/v1/ssai/beaconsets/beaconset/beacon_set_id
Header X-API-KEY: your API KEY

Sample request body

{
  "account_id": "User's Account ID [Optional]",
  "beacon_urls": [
    {
    "beacon_url": "https://myserver.com/beaconRX/load",
    "beacon_type": "Load"
    },
    {
    "beacon_url": "https://myserver.com/beaconRX/play",
    "beacon_type": "Play"
    }
  ]
}

Sample response

{
  "beacon_set": {
    "account_id": "User's Account ID",
    "beacon_set_id": "Beacon set ID",
    "beacon_urls": [{
      "beacon_url": "https://myserver.com/beaconRX/load",
      "beacon_type": "Load"
      },
      {
      "beacon_url": "https://myserver.com/beaconRX/play",
      "beacon_type": "Play"
    }],
    "updated_beacon_set": {
      "beacon_set_id": "Beacon set ID",
      "beacon_urls": [{
        "beacon_url": "https://myserver.com/beaconRX/load",
        "beacon_type": "Load"
      },
      {
        "beacon_url": "https://myserver.com/beaconRX/play",
        "beacon_type": "Play"
      }],
      "account_id": "User's Account ID"
    }
  }
}

Get beacon sets

To retrieve the beacon sets for an account, submit a GET request:

Method GET
URL https://api.bcovlive.io/v1/ssai/beaconsets/account/Account ID
Header X-API-KEY: your API KEY

Sample response

[{
    "account_id": "User's Account ID",
    "beacon_set_id": "Beacon set ID1",
    "beacon_urls": [{
    "beacon_url": "https://myserver.com/beaconRX/load",
    "beacon_type": "Load"
  }]
  },
  {
    "account_id": "User's Account ID",
    "beacon_set_id": "Beacon set ID2",
    "beacon_urls": [{
    "beacon_url": "https://myserver.com/beaconRX2/load",
    "beacon_type": "Load"
    },
    {
    "beacon_url": "https://myserver.com/beaconRX2/play",
    "beacon_type": "Play"
    }]
}]

Get beacon sets for requesting user

You can also get the beacon sets for the account of the requesting user without including the account id in the request URL:

Method GET
URL https://api.bcovlive.io/v1/ssai/beaconsets
Header X-API-KEY: your API KEY

Sample response

[{
    "account_id": "User's Account ID",
    "beacon_set_id": "Beacon set ID1",
    "beacon_urls": [{
    "beacon_url": "https://myserver.com/beaconRX/load",
    "beacon_type": "Load"
  }]
  },
  {
    "account_id": "User's Account ID",
    "beacon_set_id": "Beacon set ID2",
    "beacon_urls": [{
    "beacon_url": "https://myserver.com/beaconRX2/load",
    "beacon_type": "Load"
    },
    {
    "beacon_url": "https://myserver.com/beaconRX2/play",
    "beacon_type": "Play"
    }]
}]

Get a beacon set by id

To retrieve a single beacon set by its id, submit a GET request:

Method GET
URL https://api.bcovlive.io/v1/ssai/beaconsets/beaconset/beacon_set_id
Header X-API-KEY: your API KEY

Sample response

{
    "account_id": "User account ID",
    "beacon_set_id": "Beacon set ID",
    "beacon_urls": [{
      "beacon_type": "Load",
      "beacon_url": "https://myserver.com/beaconRX2/load"
  },
  {
    "beacon_type": "Play",
    "beacon_url": "https://myserver.com/beaconRX2/play"
  }]
}

Delete a beacon set

Finally, to delete a beacon set, send a DELETE request:

Method DELETE
URL https://api.bcovlive.io/v1/ssai/beaconsets/beaconset/beacon_set_id
Header X-API-KEY: your API KEY

Sample response

The response will look like this:

{
  "beacon_set_id": "Beacon set ID",
  "deleted": true
}

Appendix

Below is a screenshot to show a sample cue point setup for the Elemental encoder.

Elemental Cue Point Setup
Elemental Cue Point Setup