Dynamic Ad Insertion


Dynamic Ad Insertion (DAI) is one of a number of phrases used for supplementing a program stream with an alternative piece of content (an Advertisement) dynamically. DAI workflows are driven by the use of SCTE-104 and SCTE-35 metadata. The following document will provide information on how SCTE-35 is utilized within adaptive bitrate streaming. Whilst there are several other phases used to describe the same action, this document will aim to use consistent wording throughout. Further terminology used throughout this document can be found in the Glossary.

How does DAI work for Live?



For further information regarding Live use cases please see Origin Live - SCTE-35 and FFMPEG SCTE-35 Tutorial.

How does DAI work for VOD?



For further information regarding VOD use cases please see Remix AVOD

What is SCTE-35?

Metadata describing a program enabling the stream(s) to be conditioned for Ad Insertion or Ad Replacement.

Often originating from a SCTE104 message which has been translated/converted by an upstream contribution encoder or automation system.

The metadata will then be presented in the DASH manifest (adhering to SCTE-214-1 (2016)) and HLS manifest (adhering to the Apple HLS Specification (rfc8216)).

Whats the difference between SCTE-104, SCTE-35 & SCTE-214?

SCTE-104 messages are requests from an automation system to create splice markers in a program stream.

SCTE-35 messages are the fulfillment of these requests, including all of the data that a downstream system needs to take appropriate actions to condition the presentation stream.

SCTE-214-1 describes the carriage of SCTE-35 metadata within a DASH client manifest.

What are SCTE-35 markers?

Markers are events within time (relative to the program stream). These events can be both informative and actionable. The marker received by the Origin for example, could be to splice the stream enabling a client to switch between sources or pass through metadata received.

Each command can be used to describe event(s) within a program stream and changes the way metadata is signaled (in the manifest) and/or structure of the presentation.

These commands often come in the form of:

  • A legacy command (as described in Section 9.1 of SCTE-35 (2019)) to indicate where a break can occur within a program stream.
  • Still widely used in the industry (until all systems support time_signal)
  • Commands trigger either CUE-OUT (to the Ad Break) or CUE-IN (from the Ad Break) or both.
  • Breaks cannot overlap each other.
  • A successor command to indicate where a break can occur within a program stream.
  • Beginning to be adopted more in the industry.
  • Commands are supplied in pairs with each CUE-OUT/CUE-IN being used to describe a different type of Break.
  • Each can be used to decribe a different type of break (Program, Chapter, etc.


Note. For further information please see --time_signal.

Ad Insertion or Ad Replacement, what’s the difference?

Ad Replacement:
  • Can be used in both Live & VOD.
  • The advertisement is used to replace a timeframe of the main program.
  • The advertisement is simply replacing the main program therefore the duration of the program stream doesn’t change.
Ad Insertion:
  • Only applies to VOD.
  • The advertisement inserted can be any length of time defined.
  • The overall duration of the stream will be extended by whatever the length of the advertisement.

How are SCTE-35 messages received?

Unified Streaming products support the handling of:

  • splice_insert()
  • time_signal()
  • segmentation_descriptor()

And are capable of fulfilling the requirements in the following presentation formats:

  • HLS-TS
  • HLS-fMP4
  • DASH-$SegmentList
  • DASH-$Timeline
  • DASH-$Number

Product support for SCTE-35 is based upon the following specifications & guidelines:

SCTE-35 Timing Model

The following extract from the SCTE-35 specification outline the requirement for the deliver of metadata.


Section 9.2 of SCTE-35 (2019) outlines the following requirements for delivery of metadata in advance of the desired presentationTime.

The splice_insert() message shall be sent at least once a minimum of 4 seconds in advance of the desired splice time for a network Out Point condition. It is recommended that, if a return-to-network (an In Point) message is sent, the same minimum 4 second pre- roll be provided.


Section 10.3.3 of SCTE-35 (2019) outlines the following requirements for delivery of metadata in advance of the desired presentationTime.

The time_signal() or splice_insert() message should be sent at least once a minimum of 4 seconds in advance of the signaled splice_time() to permit the insertion device to place the splice_info_section() accurately.

The processing entity (in this case Origin) can receive SCTE-35 messages delivered as event message track containing:

  • DASH Events stored in an ‘emsg’ box
  • Cablelabs ESAM stored in an ‘mdat’ box
DASH Events (EMSG)

When converted to XML the message can take the following form:

<EventStream xmlns="urn:mpeg:dash:schema:mpd:2011"
value="2" timescale="10000000">
  <!-- 2019-12-19T08:30:21.942400Z -->
  <Event presentationTime="15767442219424000" duration="150000000" id="1576744212">
    <Signal xmlns="http://www.scte.org/schemas/35/2016">
        <SpliceInsert spliceEventId="1576744212"
            <SpliceTime ptsTime="1259272022" />
          <BreakDuration autoReturn="1" duration="1350000" />
Cablelabs (ESAM)
  • Part of Cablelabs ESAM specification OC-SP-ESAM-API
  • SCTE-35 messages delivered as XML
  • XML can be extracted directly from the file delivered
  • Adopted by AWS Elemental (Live, MediaLive)
<?xml version="1.0"?>
<sig:AcquiredSignal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.cablelabs.com/namespaces/metadata/xsd/conditioning/2 ESAM_Signal.xsd">
  <AcquiredSignal acquisitionPointIdentity=""
    <sig:UTCPoint utcPoint="2017-10-05T23:47:43.138Z"/>
    <sig:BinaryData signalType="SCTE35">/DAlAAAAAA4QAP/wFAUAAAACf+/+ABjGMP4ADbugAAEBAQAAbRyXaw==</sig:BinaryData>
      <sig:StreamTime timeType="HSS" timeValue="15072472620400000"/>
      <sig:StreamTime timeType="SignalID"
      <sig:StreamTime timeType="Duration" timeValue="100000000"/>

What are best practices for DAI?

Preparing your media for OTT is important to enable efficient delivery and quality of experience. It is important to understand how your content has been prepared or delivered to ensure the correct configurations are in place for the desired output.

Media alignment at splice boundaries

We recommend alignment between audio and video fragments, constant fragment durations and efficient encoding (one GOP per fragment). This will make the streaming later on more efficient, in terms of bandwidth usage, manifest sizes and for clipping and archiving of the content.

However, the introduction of SCTE-35 markers and additional IDR can have an impact on the alignment of your output. This is due to the fact AVC video (with a framerate of 25 FPS) & AAC audio (with a sample rate of 48kHz) only fully align at a 0,32s interval. If the SCTE marker does not match this interval (which is often won't) the resulting audio and video duration will not be fully aligned. The same issue can also occur with other framerates (such as 23.97, 24, 30) resulting in a different alignment interval.


Whilst normally this has no impact on quality of experience, it should be noted that poor quality of experience can occur (depending upon content, platform, player behavior).

One example would be any large change in audio level between main program and advertisement at splice points. Therefore it is recommended to review content creation guidelines and test your content before deploying in production.

Unified Origin requirements

The following requirements our placed into two sections. Ingress relates to the formatting, structure, method of delivery to the Origin enabling data to be efficiently processed. These apply to the encoding platform generating the necessary SCTE-35 marker and program. Egress relates to options configured within your Origin enabling successful delivery to the Ad Insertion Service.

  • Received as DASH event messages (contained in a emsg box inside a fMP4 container) OR Cablelabs ESAM (XML contained in an mdat inside a fMP4 container)
  • Received ahead of the desired presentation. At least 2x ahead of the target fragment length. If this is not available time shift can be used to delay the presentation live edge, allowing for correct calculation of segment duration.
  • Received as a separate track
  • Each message received must have a corresponding IDR frame for at each timestamp that is signaled in a SCTE 35 message.
  • When Inserting an IDR frame the encoder should not shorten or lengthen any of the media segments but keep the original length intact.
  • Ensure urn:scte:scte35:2013:bin is used when delivering DASH Events (emsg).
  • Always set --hls_minimum_fragment_length equal to or multiple of (if encoder splices) the GOP, unless the source encoder segmentation divides evenly into the default value of 4 seconds
  • --dvr_window_length is shorter than --archive_length to mitigate fragment length changes when transitioning from between dvr windows.
  • --dvr_window_length is set to a duration greater than the longest advertisement window ensuring each CUE-OUT and CUE-IN (for HLS) are signaled within the same timeline.
  • Only splice_insert() OR time_signal() messages can actioned upon, not both.
important configurable options
  • --timed_metadata
  • --splice_media
  • --time_signal
  • --[hls|mpd].minimum_fragment_length
  • --mpd.segment_template=[time|number]

When only --splice_media is used, we may splice a media segment (at the times given by the splice_insert() message). When both --splice_media and --time_signal are used, splice_insert() messages will be ignored. time_signal() messages instead will be used.

This results in the following (example):
  • Option A - splice_insert() --timed_metadata --splice_media
  • Option B - time_signal() --timed_metadata --splice_media --time_signal=34,35


Note. Previously it was possible to add a ?filter=EXPRESSION to remove SCTE-35 signaling from client manifests. This was removed in version 1.10.15 onwards.