Broadcasts
Next to the program, publish two more broadcasts. If the program is demo/program.hang, the cue broadcast is demo/ads.hang and the ad media broadcast is demo/ad.hang. The catalog section is adInsertion.
{
"adInsertion": {
"version": 1,
"track": "ads",
"program": "program.hang",
"ad": "ad.hang",
"groupDurationMs": 2000
}
}
Cue record
One JSON object on the ads track, carried with @moq/json. Types are cue-out, cue-in, and cancel.
{
"v": 1,
"type": "cue-out",
"breakId": "brk_2130706456",
"eventId": 2130706456,
"seq": 4,
"durationMs": 30000,
"splice": { "group": 1842, "wallMs": 1762800000000, "pts": 1620000 },
"scte35": "…base64 splice_insert…",
"autoReturn": true,
"source": "manual",
"issuedAtMs": 1762800000000
}
Decision
AdDecisionFn(breakId, durationMs, context) returns the creatives. An empty array means stay on the program. moqAdDecision({ baseUrl }) is that function.
import { moqAdDecision, moqAdBeaconSink } from "@moqad/sdk";
const decide = moqAdDecision({ baseUrl: "https://moqad.dev" });
const sink = moqAdBeaconSink({ baseUrl: "https://moqad.dev", sessionId });
const creatives = await decide(breakId, durationMs, context);
The HTTP body is the same three arguments. The response is { creatives, decisionId, eventId, breakId, beaconUrl, demo }. The function returns creatives only, which is what the fixture returned.
Eleven events
adBreakStart, adStart, impression, firstQuartile, midpoint, thirdQuartile, complete, click, skip, adBreakEnd, error. Each one includes eventId and creativeId. Send them to POST /v1/beacon.