StreamAdsPro Logo
StreamAdsProSSAI Platform
StreamAdsPro Cue

SCTE-35 marking & detection

Write ad-break markers into a playlist, read the cues that are actually there, and prove the signalling survives every hop between your encoder and the player.

Audit my pipeline

SCTE-35 signals the break. It does not fill it.

SCTE-35 does not insert the ad. It signals the opportunity. A separate system — an SSAI server, AWS MediaTailor, Amagi — reads the marker and decides what to stitch in.

Cue works on that signal: writing it, reading it back, and checking it is still intact further down the chain.

Three jobs

Everything Cue does is one of these three.

ModeJobWho needs it
MarkWrite breaks into a playlist from a JSON cue sheetContent owners preparing VOD / FAST inventory
DetectRead the cues actually present in any playlist or live URLAnyone debugging a pipeline they did not build
ValidateAssert the signalling is correct, paired and decodableProving a break works before it goes live

Marking a file is a solved problem. Finding out where a cue dies between the encoder and the player is not.

Tag forms Cue recognises

Vendors disagree about how to write the same cue. Cue reads all of these on the way in.

TagEmitted by
#EXT-X-CUE-OUT / #EXT-X-CUE-INalmost everything
#EXT-X-CUE-OUT-CONTmid-break continuation
#EXT-X-DATERANGE + SCTE35-OUTApple HLS spec (RFC 8216)
#EXT-OATCLS-SCTE35AWS Elemental / MediaPackage
#EXT-X-SCTE35:CUE=older Elemental
#EXT-X-SPLICEPOINT-SCTE35other packagers

Run it at every hop

Check the cues at each stage of a pipeline you did not build.

● At the source
does the source carry cues?
● After the packager
did the packager keep them?
● At the ad server
did the ad server see them?

The hop where the cue count drops is the hop that broke it.

What marking writes

Both the text form and the binary form, because different consumers need different things.

#EXT-X-CUE-OUT:30.000
#EXT-X-DATERANGE:ID="ad-break-1",PLANNED-DURATION=30.000,SCTE35-OUT=0xFC3025...
...break segments...
#EXT-X-CUE-IN

For the player

#EXT-X-CUE-OUT tells a player a break is starting.

For the ad server

The SCTE35-OUT binary payload is what an SSAI server or MediaTailor actually parses.

Text-only signalling is the single most common reason a break “does not work” downstream.

Where Cue is today

CapabilityState
File / VOD markingWorking
Binary splice_insert encode + decodeWorking
Detection across vendor tag forms, file or URLWorking
Validation + audit reportingWorking
time_signal + segmentation descriptorsPlanned
Live manifest proxy (mark a running 24/7 stream)Planned
MPEG-TS binary PID embeddingPlanned

Runs anywhere

The encoder is dependency-free — pure Python standard library, so it runs on a client’s laptop with nothing installed.

Gates a pipeline

validate exits 0 on pass and 1 on fail, so it gates a CI pipeline.

What a cue actually is

An SCTE-35 cue is a promise about the future. It says: thirty seconds from now, this stream reaches a point where an advert may be inserted, and that opportunity lasts for a stated duration. It carries no video and no advert — only the timing, an event identifier, and enough structure for a machine downstream to act on it without guessing.

That indirection is the whole point, and also the whole problem. The system that knows when a break happens is usually the playout automation, sitting at the very start of the chain. The system that has to do something about it — an ad server, a stitcher, a packager — sits at the end. Between them are several hops, each of which is entitled to re-segment the stream and rewrite the playlist. A packager that does not recognise a tag will often drop it rather than pass it through, and it will do so silently, because from its point of view nothing went wrong.

So the failure mode is almost never a loud one. The stream plays perfectly, the ad break simply never fires, and the first person to notice is whoever reconciles the delivery report against the booking. By then the inventory is gone. Reading the playlist at each hop, rather than only at the player, is what turns that into a five-minute answer.

SCTE-35 questions

What is SCTE-35?
SCTE-35 is the broadcast standard for signalling an advertising opportunity inside a video stream. It does not carry the advert itself; it carries a timed marker that says a break starts here and lasts this long. Everything downstream - ad server, packager, stitcher - reads that marker to decide what to do. In HLS the markers surface as playlist tags such as EXT-X-CUE-OUT, EXT-X-CUE-IN and EXT-X-DATERANGE.
Why do SCTE-35 cues go missing between the encoder and the player?
Because every hop is allowed to rewrite the playlist. An encoder emits a splice_info_section, a packager re-segments and may drop tags it does not understand, a CDN caches an older variant, and a player only ever sees the end result. Each stage behaves reasonably on its own, and the cue still disappears. The only reliable way to find the guilty hop is to read the playlist at each one rather than at the end.
What is the difference between marking and detecting cues?
Detection reads a stream you already have and tells you which cues exist, where they land and whether their payloads parse. Marking writes new cues into a stream that has none - useful when your source is a clean feed and your ad system needs break signalling that nobody upstream is producing. Cue does both, and validating after marking is the step most workflows skip.
Do I need SCTE-35 markers to insert ads with StreamAdsPro?
No. Server-side insertion driven by a schedule expression - a thirty-second spot every ten minutes, for example - needs no markers at all, which is how most channels start. SCTE-35 matters when the break times are decided upstream by a playout system or a rights contract rather than by you, or when an ad server has to be told about the opportunity in advance.
Which HLS tags does Cue understand?
The common CUE-OUT and CUE-IN pair, EXT-X-DATERANGE with its SCTE-35 attributes, and the OATCLS-SCTE35 form emitted by several commercial packagers. Where a base64 splice_info_section is present it is decoded and checked rather than just matched as text, because a tag that is present but malformed fails in exactly the same way as a tag that is absent.
Free, no account

Send us your HLS stream URL. We will show you where the SCTE-35 cue is lost.

You get a plain report: which cues are present, whether every break opens and closes, whether the durations agree, and the first hop where the signal disappears. One URL, one working day, and no obligation to buy anything.

Not sure where your cues are dying?

Send us the hops and we will tell you which one drops the signal.

WhatsApp