FirstByte Stream plays ads in ad breaks. A break has a start time and a length. During a break, the player shows ads in a layer above the content. For a live stream, the stream continues under the ads with no sound, and the player goes back to it when the break ends. For a recorded (VOD) asset, the player stops the content, plays the ads, and then continues. This page explains:
  • how a live stream gets ad breaks,
  • where the ads come from (your own ad videos, or your ad server),
  • what the player does and which events it sends.

Ad breaks on a live stream

A live stream gets an ad break in one of two ways. FirstByte Stream puts each break on a separate track of the stream, the cues track. The track uses the MoQ event timeline format and carries the SCTE-35 message. All viewers get the same break at the same point of the stream, so the break starts at the same frame for every viewer.

Insert a break from the console

  1. Open Live inputs and select the input.
  2. In the Ad breaks card, set the length (5 to 600 seconds).
  3. Select Insert ad break.
The input must be live. The break starts at the newest frame of the stream.

Insert a break with the API

The webhook streams.ad_break.inserted tells you that a break was sent to the stream.

SCTE-35 from the encoder

Only the SRT ingest reads SCTE-35. Put the SCTE-35 messages on a PID with stream_type 0x86, and put a CUEI registration descriptor in the PMT. FirstByte Stream reads:
  • splice_insert with out_of_network_indicator set: the start of a break, with its break_duration.
  • splice_insert with the cancel flag: the break is cancelled.
  • splice_insert without out_of_network_indicator: return to the program.
  • time_signal with a segmentation descriptor of a start or end type.
splice_null heartbeats are ignored. An encrypted splice_info_section is ignored.

Where the ads come from

Each live input has an ad decision setting. It tells the platform where the ads of a break come from.

Ad videos

Use Ad videos in the Ad breaks card to choose up to 20 of your VOD assets. An asset can be an ad video only when all of these are true:
  • its status is ready,
  • it was transcoded (it has a CMAF ladder),
  • it does not need signed URLs.
For each break, the platform starts at a position in your list that depends on the break, and adds videos in order until their total length fills the break. All viewers of one break get the same videos. API: streams.liveInputs.setAdAssets({ orgId, id, assetIds }).

VAST tag

Select VAST tag and enter your ad server’s tag URL. Then select Test tag. The test calls the tag once and shows the ads that it found: the title, the length, the media file that the player will use, and whether the ad can be skipped. A test sends no impression or tracking requests. API: streams.liveInputs.setAdDecision({ orgId, id, mode: 'vast', vastTagUrl }). Rules for the tag URL:
  • It must start with https://.
  • It must not point at a private, loopback or cloud metadata address.
  • It can be at most 4096 characters.
For each viewer and each break, the platform calls your tag. It sends the viewer’s IP address and user agent in the X-Device-IP, X-Forwarded-For, User-Agent and X-Device-User-Agent headers. It follows VAST wrappers to a depth of 5. The whole call has a limit of 3.5 seconds. If your ad server does not answer, or returns no ads, the viewer gets your ad videos, or no ads. The platform supports VAST 2.0, 3.0 and 4.x linear ads. Ads with a sequence attribute make a pod, in sequence order. It uses stand-alone ads to fill the rest of the break. It chooses a media file in this order: progressive MP4, then WebM, then HLS. VPAID creatives and http:// media files are not used.

Macros in the tag URL

The platform replaces these macros in your tag URL before it calls it: Macros that the platform does not know stay in the URL as they are.

OpenRTB (Prebid)

Use this when you have accounts with SSPs (bidders) but no ad server of your own. The platform runs the auction in its own Prebid Server.
  1. Open Settings → Ads → OpenRTB demand.
  2. Turn it on and add your bidders. Each bidder has a code (for example appnexus) and the parameters that the bidder gave you. The console lists the bidder codes that Prebid Server knows.
  3. Set the floor price (CPM), the currency and the auction timeout (200 to 1500 ms).
  4. On the live input, set Ad decision to OpenRTB (Prebid).
API: streams.ads.setOpenRtb({ orgId, enabled, bidders, floorCpm, currency, tmaxMs, gdprDefault, test, ... }). For each viewer and each break, the platform sends one OpenRTB 2.6 request. The request has one in-stream video slot for each 15 seconds of the break (at most 6), with the pod fields podid, slotinpod and poddur. It includes the page, the viewer’s user agent and IP address, your supply chain node, and the viewer’s consent signals. The winning bid’s VAST goes through the same rules as a VAST tag. The platform sends the win notice (nurl). The player sends the billing notice (burl) when the ad starts. Without bidder accounts, the auction returns no bids, and the break uses your ad videos. Give the player the viewer’s consent signals from your consent management platform. The player sends them with each ad request, and they fill the [GDPR], [GDPRCONSENT], [US_PRIVACY], [GPP] and [GPP_SID] macros:
On the element, use the attributes ad-gdpr, ad-gdpr-consent, ad-us-privacy, ad-gpp and ad-gpp-sid. If the page gives no GDPR signal, the OpenRTB request uses the organization’s GDPR default (on, unless you change it).

Ads on a recorded asset (VMAP)

A VOD asset can have an ad tag. Open the asset’s playback endpoints and use Ads: API: streams.assets.setAdTag({ orgId, id, kind: 'vmap' | 'vast' | null, url }). The platform reads the VMAP AdBreak elements with a linear breakType. It supports these timeOffset values: start, end, HH:MM:SS(.mmm) and n%. It does not support #n (position). Each break can use an AdTagURI or an inline VASTAdData. The platform keeps the VMAP document for 5 minutes. The player:
  • plays a pre-roll before the content starts,
  • stops the content at a mid-roll, plays the break, and continues,
  • plays a post-roll when the content ends,
  • plays each break one time for each page load.
If a viewer seeks forward past breaks that did not play, the player plays the last of those breaks one time, and then continues from the seek position.

What the player does

The <clutchcall-player> element and the StreamPlayer class do all of the above when ads is on (the default). To turn ads off, set ads: false. During a break, the player shows:
  • the label Ad i of n with the time that remains,
  • Skip ad, when a VAST ad allows a skip and the skip time has passed,
  • Learn more, when a VAST ad has a click-through URL. It opens the URL in a new tab and pauses the ad.
The player sends the VAST tracking requests: impression, creativeView, start, the quartiles, progress, complete, mute, unmute, pause, resume, skip, click tracking, and error with an error code (400, 402 or 405). It sends each request one time.

Player events

A live break has eventId (the SCTE-35 event id). A VOD break has breakId.