Scheduling ads

The source.ads API for scheduling, listing and controlling ads

On a content source, the advertising API is available under the ads namespace of the source API. It lets you schedule ad tags, inspect what is scheduled, and control the currently playing ad.

interface ContentSourceAdvertisingApi {
  readonly isAd: false;
  readonly isLinearAdActive: boolean;

  schedule(config: AdConfig): AdPod;
  discard(adPodOrAdBreak: AdPod | AdBreak): void;
  list(): AdBreak[];
  getActiveAdBreak(): AdBreak | undefined;
  getActiveAdPod(): AdPod | undefined;
  getActiveAd(): Ad | undefined;
}

Scheduling an ad

Call schedule with an AdConfig. The player fetches and parses the ad tag, then plays it at the requested position.

const sourceApi = player.sources.add(sourceConfig);

// Pre-roll
sourceApi.ads.schedule({
  tag: { type: 'vast', url: 'https://YOUR-AD-SERVER/preroll.xml' },
  position: 'pre',
});

// Mid-roll at 30 seconds
sourceApi.ads.schedule({
  tag: { type: 'vast', url: 'https://YOUR-AD-SERVER/midroll.xml' },
  position: 30,
});

// Post-roll
sourceApi.ads.schedule({
  tag: { type: 'vast', url: 'https://YOUR-AD-SERVER/postroll.xml' },
  position: 'post',
});

AdConfig

type AdConfig = {
  id?: string;
  tag: AdTagConfig;
  position?: number | string;
  preloadConfig?: PreloadConfig;
};

type AdTagConfig = {
  type: AdType;      // 'vast' | 'vmap'
  url: string;
};

type PreloadConfig = {
  adManifestPreloadOffset?: number;
  adSourcePreloadOffset?: number;
};
  • tag.type'vast' for a single VAST ad tag, 'vmap' for experimental VMAP support
  • tag.url — the ad tag URL to fetch.
  • position — where the ad plays. See Ad positions below.
  • preloadConfig — how far ahead of the position the ad manifest and ad source are fetched.
  • id — an optional identifier; one is generated when omitted.
📘

VMAP Support

Proper VMAP support has not yet been implemented and you may therefore experience playback issues when scheduling VMAP ads. We suggest using only VAST ads for production deployments for the time being.

Ad positions

position accepts either a number of seconds or a string:

ValueResolves to
0 (default)Pre-roll (start of content)
a positive numberThat many seconds into content
'pre' / 'start'Start of content
'post' / 'end'End of content (post-roll)
'50%'Percentage of content duration
'12.5'Numeric string, seconds

Positions are clamped to the content duration. Percentage and end positions depend on the content duration being known — a percentage ad on a source whose duration is not yet resolved is scheduled once the duration becomes available.

Inspecting scheduled ads

schedule returns an AdPod. Scheduled ads are grouped into ad breaks by position — list() returns the AdBreaks, each containing one or more AdPods, each containing one or more Ads.

const breaks = sourceApi.ads.list();
const activeAd = sourceApi.ads.getActiveAd();

if (sourceApi.ads.isLinearAdActive) {
  console.info('A linear ad is currently playing');
}

Removing scheduled ads

Use discard with an AdPod or AdBreak to remove it before it plays.

const pod = sourceApi.ads.schedule({
  tag: { type: 'vast', url: 'https://YOUR-AD-SERVER/midroll.xml' },
  position: 30,
});

sourceApi.ads.discard(pod);
📘

Discarding an ad break removes its pods

discard(adBreak) removes the pods contained in the break.

The Ad object

An Ad describes a single ad. Beyond static fields (id, externalAdId, state, position, isLinear, skipDelay, clickThrough, companions, icons, ...), it is capability-typed: a set of boolean flags declares which controls the ad supports, and narrowing a flag reveals the matching methods and properties.

type Ad = {
  readonly id: string;
  readonly state: BaseAdState;
  readonly isLinear: boolean;
  readonly clickThrough?: ClickThrough;
  readonly companions: readonly CompanionAd[];
  readonly icons: readonly AdIcon[];

  readonly canPause: boolean;
  readonly canSkip: boolean;
  readonly canSetVolume: boolean;
  readonly canExpand: boolean;
  readonly hasTimeline: boolean;
  // ...
};

The capability flags gate the extra members:

FlagWhen true, the ad also has
canPausepaused, play(), pause()
canSkipskip()
canSetVolumevolume (getter/setter)
canExpandexpanded (getter/setter)
hasTimelineduration, currentTime

Check the flag before using the member. In TypeScript, narrowing on the flag makes the member type-safe:

const ad = sourceApi.ads.getActiveAd();

if (ad?.canSkip) {
  ad.skip(); // typed and available only inside this branch
}

if (ad?.canPause) {
  ad.pause();
}

if (ad?.canSetVolume) {
  ad.volume = 0.5;
}

Accessing a control for a capability the ad does not support is not allowed — the getter returns undefined and the setter throws — so always gate on the flag.