Understanding broadpeak.io behavior

What does broadpeak.io actually do?

broadpeak.io is a platform built for developers with the purpose to build better, faster and more resilient media applications within the spectrum of content contextualization and personalization.

What is media content contextualization?

A whole set of applications and use-cases can be answered with content contextualization such as Blackout, Simsub, Channel assembly, Ad Insertion, etc., the objective being to adapt the content delivered to given Audiences, (group of viewers), based on contextual information (location, devices, time, etc.). The platform takes live and on-demand feeds and adapts them by replacing or stitching the streams with contextualized content. Contextualization is defined through rules which you can configure and have full control over.

Reference timing & synchronization

📘

Time synchronization matters!

It is very important that you take time synchronization into account when implementing your application with broadpeak.io, as a de-synchronization of couple of seconds between your programming system, your origin packager and broadpeak.io might not lead to the expected outcome.

broadpeak.io allows external systems such as a scheduling system to create what we call a slot, which is basically a period of time which starts at a known point of time, and which finishes at another known point of time. A slot can also contain additional information such as Audience information (the people that this slot addresses), and some Action information (what is expected to happen during this period). A slot is also called a MediaPoint under the ESNI specifications.

When scheduling systems define ESNI MediaPoints to create Content Replacement slots, they need to provide a matchTime value - as in the example below. The value of this attribute reflects the time when the slot should start. See below for example with a case of Blackout.

<Media href="MyBlackoutService">
  <MediaPoint id="MyMediaPoint" matchTime="2021-08-18T16:00:00Z" expectedDuration="PT0H1M">
   .....
  </MediaPoint>
</Media>

Note: The xml above is not a fully functional xml body. Parts that are not relevant for the example have been omitted.

This time information is then taken into account by the platform to perform the switch to the indicated alternate channel (if specified) for the right Audience (if specified), at the right time. Indeed, the platform compares the MediaPoint matchTime value with the internal clock to trigger the switch from the original source to the replacement source. It is only when the internal clock has reached the matchTime value, that broadpeak.io initiates the manifest contextualization process.

Note: the platform’s internal clock is synchronized through Amazon Time Sync Service. More information can be found on AWS website.

Period of consideration for Source & Service creation

When creating or updating a Source or a Service, there is a necessary delay for the platform to take into account the information, propagate it, and use it as replacement content. This delay is maximum 15 seconds.
To translate this into the implementation of the scheduling logic, this means that the Source should be created at least 15 seconds before you want to see the program scheduled onto the stream.

Example:

  • If we want to schedule a program to start at 2022-12-20T16:20:00.000Z which relies on Source X, the Source should be created before 2022-12-20T16:05:00.000Z.

Timeout management

broadpeak.io handles HTTP requests timeout in the same way for all services and users. It has timeout thresholds values defined globally that cannot be changed. We know this is not the best, and we are working on allowing more flexibility in the near future.

  • Timeout to Origin Server(s): 5 seconds. Timeout error message returned is "Bad gateway from origin server".
  • Timeout to Ad Server (s): 2 seconds. Timeout error message returned is "Bad gateway from origin server".

The platform has a global timeout of 5 seconds.

Contextualisation process

The system looks for the right place in the original manifest to insert the reference to the replacement content using the actual content PDT that it retrieves or computes directly from the manifest.

🚧

Important

Your origin packager and programming system must be synchronized in time with broadpeak.io. A manifest which presents a time that is late in comparison to broadpeak.io internal clock can lead to missed slots, or delayed slot start time.

In HLS, broadpeak.io uses PDT (Program Date Time) as reference timing for the manifest.
In MPEG-DASH, broadpeak.io uses the timing information of the segment timeline specified inside the manifest as reference timing.

Time Precision

The process may be more or less precise when it comes to timing of contextualization commands. The way broadpeak.io handles timing precision is different based on the type of Application implemented on the platform. See the relevant section below for details.

Virtual Channel and Content Replacement Applications

Slot precision

The precision of the platform when using the Virtual Channel or Content Replacement Applications is 1 second.

With a 1 sec precision, this means that if the programming system defines a matchTime with a value in milliseconds, the platform will automatically round the time to the nearest second.

Sometimes, the matchTime value indicated is not exactly between the end time of a media segment and the start time of the next segment. The following sections explain how this scenario is being handled in HLS and MPEG-DASH:

Management of slot start time between two media segments in HLS

HLS Media playlists directly reflect the media segments through the numbering syntax. Each media segment has a duration, which in most cases, is the same for all media segments.
In the event that the matchTime of the MediaPoint is not exactly between the end time of one media segment and the beginning of the next media segment, broadpeak.io identifies the start time of the last segment before the matchTime value, and starts inserting the reference to the media segments of the alternate content there.

Example:
Assuming we have an original content whose media manifest reflects a 4-second media segment. This media manifest shows that the last available video segment starts at 12:00:00 and ends at 12:00:04 (11:59:40 + 5 x 4 sec segments). Here is how the original manifest would look like:

#EXTM3U                                                                                                              
#EXT-X-VERSION:5
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:4
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T11:59:40.000000+00:00
#EXTINF:4, no desc
audio=129117-video=633990-01.ts
#EXTINF:4, no desc
audio=129117-video=633990-02.ts
#EXTINF:4, no desc
audio=129117-video=633990-03.ts
#EXTINF:4, no desc
audio=129117-video=633990-04.ts
#EXTINF:4, no desc
audio=129117-video=633990-05.ts
#EXTINF:4, no desc
audio=129117-video=633990-06.ts

Assuming we have a programming system that creates a MediaPoint with a matchTime at 2022-11-10T12:00:02.456Z:

  1. As the precision of the platform is 1 second, the recorded matchTime gets rounded to 2022-11-10T12:00:02.000Z.
  2. Then, as 2022-11-10T12:00:02.000Z does not exactly fall at the end of an existing media segment, broadpeak.io starts inserting reference to media segments of the alternate source at 2022-11-10T12:00:00.000Z, i.e. before the last segment. The last segment of the original content audio=129117-video=633990-06.ts is therefore replaced by the latest segment available on the manifest of the replacement source.
#EXTM3U                                                                                                              
#EXT-X-VERSION:5
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:4
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T11:59:40.000000+00:00
#EXTINF:4, no desc
audio=129117-video=633990-01.ts
#EXTINF:4, no desc
audio=129117-video=633990-02.ts
#EXTINF:4, no desc
audio=129117-video=633990-03.ts
#EXTINF:4, no desc
audio=129117-video=633990-04.ts
#EXTINF:4, no desc
audio=129117-video=633990-05.ts
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T12:00:00.000000+00:00
#EXTINF:4, no desc
../../../../replacement_content/hls/audio=129117-video=633990-190.ts

The example above explains how it works with a single variant, but obviously this mechanism is applied to all the existing variants requested by the player.

Management of slots start time between two media segments in MPEG-DASH

In MPEG-DASH, the slot precision of 1 sec also applies.

The handling of these scenarios in MPEG-DASH is slightly different, as the protocol allows more flexibility with the multi-period syntax. Indeed, in MPEG-DASH it is possible to represent several periods in which media segments could overlap. The start point of a period automatically signals the end of the previous period, regardless of how long that previous period's content is.

In the event that the matchTime of the MediaPoint is not exactly between the end time of one media segment and the beginning of the next media segment, broadpeak.io sends out a MPD which reflects overlapping segments across two different periods.

We are reusing the previous example where the programming system creates a mediapoint with a matchTime at 2022-11-10T12:00:02.456Z.

  1. As the precision of the platform is 1 second, the recorded matchTime gets rounded to 2022-11-10T12:00:02.000Z.
  2. Even though 2022-11-10T12:00:02.000Z does not exactly fall at the end of an existing media segment, broadpeak.io represents the alternate content in an another period at 2022-11-10T12:00:02.000Z, which automatically translates to the end of the previous period at the very same timing.
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" type="dynamic"> 
  <Period id="1" start="PT1668081000.00S"> 
  <!-- Period 1, starting at 2022-11-10T11:50:00.000Z-->
    <BaseURL>../../../dash/originalcontent/</BaseURL> <!-- path points to original content -->
    ...
    <AdaptationSet ...>
      <SegmentTemplate timescale="60000" presentationTimeOffset="100084860000000">
        <SegmentTimeline>
          <S t="100084860000000" d="120000" r="299" />
        </SegmentTimeline>
      </SegmentTemplate>
      <Representation id="video=991000" ... />
      <Representation id="video=2971000" ... />
    </AdaptationSet>
  </Period> 
  <Period id="2" start="PT1668081602.00S">  
  <!-- Period 2, starting at 2022-11-10T12:00:02.000Z -->
    <BaseURL>../../../dash/replacementcontent</BaseURL> <!-- path points to replacement content -->
    ...
     <AdaptationSet ...>
      <SegmentTemplate timescale="60000" presentationTimeOffset="100084896120000">
        <SegmentTimeline>
          <S t="100084896120000" d="120000" r="5" />
        </SegmentTimeline>
      </SegmentTemplate>
      <Representation id="video=991000" ... />
      <Representation id="video=2971000" ... />
    </AdaptationSet>
  </Period>
</MPD>

Note: The manifest above is not a fully functional MPD. Parts of the MPD structure that are not relevant for the example have been omitted.

As MPDs are not always easy to interpret, here is a graphical representation of the example.

1008

Note: Whether the last media segment of the first period is fully or only partially presented in the client (i.e. player) is up to each client. The recommendation is it should only show a partial segment until switching to the next period.

For more information, we invite you to check the following section of the DASH-IF implementation guidelines

Precision of program duration

The duration of Asset Sources is not always an integer number of seconds, but rather a float that is a combination of seconds and milliseconds. In the case of a content-replacement slot, the duration specified in the API call must be rounded down to the second below.

Example: The duration of a program is 600s and 80ms. In this case, the time to be used as the duration value in the Slot is 600 seconds.

Consequences of slot duration inaccuracy

Below is a description of what would happen if the duration defined in a replacement slot did not exactly match the duration of the replacement asset or live event.

VOD as a replacement source

If the specified duration is shorter than the total duration of the VOD, the VOD will only be inserted for the specified duration, and the end of the VOD will be truncated.

If the specified duration is longer than the total duration of the VOD, the VOD will be looped and reinserted again until the duration specified for the slot is reached. The last repetition may be truncated if the duration of the slot is not an exact multiple of the VOD source.

Live as a replacement source

If the specified duration is shorter than the total duration of the Live event, the replacement Live will only be inserted for the specified duration. The end of the event will then be truncated. Note that in case a live event is longer than initially expected, it is possible with broadpeak.io to extend the duration of the existing slot with an update.

If the specified duration is longer than the total duration of the Live event, the replacement Live will be inserted only for the specified duration. This means that the content on the Live source will be inserted, even after the end of the actual program. Note that in case the live event to be inserted is shorter than initially expected, it is possible with broadpeak.io to reduce the duration of the slot with an update.

Scheduling a program in the past

Creating a replacement slot with an end in the past is accepted by the API, but will have no effect.
Any replacement slot scheduled in the past with an end in the future will be scheduled and will take effect immediately after the consideration period. The manifest will reference the program where it should be at the time of the streaming.

Example

A VOD asset of 60 minutes is scheduled at 22/06/2022, 16:00 UTC. The API call is sent at 22/06/2022, 16:30 UTC. When retrieving the manifest at 16:30, the manifest will reference the content of the VOD, 30 minutes, in the VOD content.

Slots consideration and reflection period

When creating or updating a slot, there is a necessary delay for the platform to take into account the information, propagate it and reflect it into the manifest. This delay is 15 seconds.
When it comes to implementing any scheduling logic, you therefore need to ensure that any API call made to create or update a slot must be done at least 15 seconds before you want to see the change reflected in the stream.

Example

  • If we want to schedule a program to start at 2022-12-20T16:20:00.000Z, the API call to create the slot must be sent before 2022-12-20T16:05:00.000Z
  • If we want to extend the duration of a program which is initially supposed to end at 2022-12-20T16:47:30.000Z, the API call to update the slot must be sent at least 15 seconds before the end of the initial scheduled event, so at the latest at 2022-12-20T16:47:15.000Z. The duration value in this call can then be altered to the new actual (or expected) duration.

Dynamic Ad Insertion Application

Ad Insertion Precision

The precision of the platform when using the Dynamic Ad Insertion Application is 1 millisecond. Therefore when SCTE-35 markers are received in live manifests with ad replacement instructions, broadpeak.io will be accurate to the millisecond in processing these instructions.

Ad Insertion logic

  1. Without Transcoding involved
    When no transcoding Service is associated to the DAI Service, it is expected that the creatives are transcoded and packaged outside of broadpeak.io. It is also expected that the VAST response will contain m3u8 or mpd MediaFiles.
    In the case where the VAST response does not contain m3u8 or mpd MediaFiles, no insertion will be performed.
  2. With Transcoding involved
    As soon as a transcoding Service is associated to a DAI Service, it is expected that the flow will go through the transcoding and preparation of the creatives through broadpeak.io so they can be delivered in HLS and MPEG-DASH formats.

Gap Filler's behavior for live ad replacement

Gap fillers are used to fill the gap between the total duration of all inserted Ads and the original commercial break duration, in case the durations do not match and the break duration is longer than the sum of all inserted ads. They tremendously increase the quality of experience by avoiding switching back into and the middle of the original ads.
Gap fillers can only be used with Live Ad Replacement applications.

Below are the expected behaviors when associating a gap-filler with an Ad insertion services.

  1. With gap filler configured
    In case the VAST returned by the Ad Server contains valid MediaFiles, the gap filler will be used only if the total duration of all creatives is less than the Ad break duration.
    In case the VAST returned by the Ad Server does not contain valid MediaFiles, the gap-filler will be used to fill the total duration of the break.
  2. Without a gap filler configured
    In case the VAST returned by the Ad Server contains valid MediaFiles, and the total duration of all creatives is less than the Ad break duration, the break will not be completely filled, and the manifest will switch back to the original source, possibly in the middle of the original ad payload.
    In case the VAST returned by the Ad Server does not contain valid MediaFiles, the insertion will not be performed and the original ads will be shown.

📘

In HLS, the segment size of the slate directly impacts its capabilities to fill the break.

Ad Insertion with Subtitles in HLS

When implementing Ad Insertion applications with Sources that contains subtitles or captions, compatibility issues are often met because Ad creatives do not contain subtitles tracks. In HLS, if a stream starts with a subtitling variant, and this variant becomes unavailable for the period when the Ad is inserted, it will often create issues at the player level.

To avoid this problem, broadpeak.io implements specific logic:

The original stream is analysed and if a subtitle track is detected, the Ad inserted in the Manifest will contain reference to dummy subtitles segments as illustrated below.

Example of Live Ad replacement
The HLS subtitle variant playlist generated by broadpeak.io would look like the following:

#EXTM3U 
#EXT-X-VERSION:5 
#EXT-X-INDEPENDENT-SEGMENTS 
#EXT-X-MEDIA-SEQUENCE:0 
#EXT-X-TARGETDURATION:6 
#EXT-X-PROGRAM-DATE-TIME:2011-01-01T00:00:01.000000+00:00 
#EXTINF:4.0001, no desc 
originalstream_12451841_deu=8000-391772911.webvtt 
#EXTINF:4.0001, no desc 
originalstream_12451841_deu=8000-391772912.webvtt 
#EXTINF:4.0001, no desc
originalstream_12451841_deu=8000-391772913.webvtt 
#EXTINF:4.0001, no desc
originalstream_12451841_deu=8000-391772914.webvtt 
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2011-01-01T00:00:19.016000+00:00  
#EXTINF:4.0001, no desc
/empty.webvtt
#EXTINF:4.0001, no desc 
/empty.webvtt
#EXTINF:4.0001, no desc 
/empty.webvtt
#EXT-X-DISCONTINUITY 
#EXT-X-PROGRAM-DATE-TIME:2011-01-01T00:00:31.016300+00:00  
#EXTINF:4.0001, no desc 
originalstream_12451841_deu=8000-391772920.webvtt 
#EXTINF:4.0001, no desc 
originalstream_12451841_deu=8000-391772921.webvtt 
#EXTINF:4.0001, no desc 
originalstream_12451841_deu=8000-391772922.webvtt 
#EXTINF:4.0001, no desc 
originalstream_12451841_deu=8000-391772923.webvtt 

🚧

Limitations

  • This functionality only applies to the WebVTT subtitling format. Other subtitling formats are not supported.
  • In Live, the original content must be packaged so the subtitling variant playlist is aligned on media variants at the beginning and the end of the Ad break.
  • Only segmented WebVTT is supported. For VOD it is common to have a single WebVTT file with all the subtitle data. This use case is not a supported.
  • In case a WebVTT media segment is not aligned with the rest of the media variants, broadpeak.io will not be able to insert dummy WebVTT segments.

Matching HLS audio and video variants

Many HLS players are very sensitive to changes in stream and more specifically to codec changes within the same stream. The broadpeak.io platform is designed to maintain the best quality of experience (QoE).
For this reason, it only performs manifest contextualization if the content sources and the original source are prepared in compatible ways.

To do so, broadpeak.io looks for compatibility between the variants of the original and replacement content. The sections below highlight a set of rules for determining this compatibility.

Matching HLS variants with multiplexed audio and video

📘

Summary: multiplexed HLS audio and video tracks

  1. Codecs. broadpeak.io looks at the CODECS attribute on variants to determine compatibility between original and replacement content. No codec compatibility = no contextualisation. Transcoding profiles are also taken into account in the comparison.
  2. Languages. broadpeak.io looks at LANGUAGE compatibility between original and replacement content. If languages are different, variants with no correspondence in the replacement content are matched with the DEFAULT=YES compatible variant.
  3. Bandwidth. If there is codec compatibility, broadpeak.io looks at the BANDWITDH value, and matches a variant with the variant that has the closest bandwidth value in the replacement content.

1. Codec compatibility of multiplexed audio and video variants**

Codec information is retrieved from the attribute CODECS in the #EXT-X-STREAM-INF tag as per below:

#EXT-X-STREAM-INF:BANDWIDTH=833000,AVERAGE-BANDWIDTH=758000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=426x240,FRAME-RATE=25,AUDIO="audio-aacl-63",CLOSED-CAPTIONS=NONE
replacementcontent-audio_63340_eng=63200-video=643600.m3u8

Since audio and video are multiplexed, the codec attribute contains two values separated by a comma, which describe the audio and the video codecs of the track. The compatibility check is performed on both audio and video codecs, so if a track is compatible with the video codec but not with the audio codec - or vice-versa - it is considered not compatible.

Any video track that does not have a compatible match leads to a global incompatibility that results in a contextualization error. In this case, the original manifest is returned.
If all video tracks have a compatible match, the next compatibility rule applies.

2. Language compatibility of multiplexed audio and video variants**

In Content Replacement applications, it is common to perform content switches from national or international content to regional content. Therefore, original and replacement content often contain different languages and a different number of standalone audio tracks. Here as well, compatibility rules need to be applied.

broadpeak.io looks at the language of the codec-compatible remaining variants, and uses the audio rendition identifier that is described in each variant (with AUDIO) to identify which languages renditions are available. In the example below, the audio rendition identifier is audio-aacl-63.

# AUDIO groups
# Primary audio, multiplexed with video
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-63",NAME="English",LANGUAGE="eng",DEFAULT=YES,CHANNELS="2"
# Alternate standalone audio rendition
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-63",NAME="Spanish",LANGUAGE="spa",CHANNELS="2",URI="replacementcontent-audio_63350_spa=63200.m3u8"

# Variants
#EXT-X-STREAM-INF:BANDWIDTH=833000,AVERAGE-BANDWIDTH=758000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=426x240,FRAME-RATE=25,AUDIO="audio-aacl-63",CLOSED-CAPTIONS=NONE
replacementcontent-audio_63340_eng=63200-video=643600.m3u8

The audio rendition describes the language of each Audio variants available in the group with the attribute LANGUAGE; this is the value that broadpeak.io uses to retrieve the language available in the replacement content.

📘

Note

broadpeak.io does not maintain an ISO-639-1 to ISO-639-2 mapping table. Please make sure both original and replacement content use the same language code syntax or they will be considered incompatible.

If there is no exact language match, broadpeak.io attempts to match the audio tracks from the original content to the audio variant which has the DEFAULT=YES attribute within the audio group. Indeed, it is better for a player to have an audio track that is not the same language, than no audio at all - which in most cases would result in an error during playout.

More audio variants in the original content than in the replacement content
Let's assume a single audio rendition group with two languages in your original content, English (en) and Spanish (sp), and a single audio rendition group with a single audio track in English (en) in your replacement content. For the sake of the example let's also assume that both audio rendition groups are codecs compatible. Graphically, this would look like this:

982

Since there is no Spanish audio track equivalent in the replacement content, broadpeak.io's contextualization mechanism looks for a codec compatible track that has the attribute DEFAULT=YES - in our case it is the English track - and considers it as a match.

Once the media manifest is contextualized, the variant with the Spanish audio track will reference English media segment of the replacement content.

982

Fewer audio variants in the original content than in the replacement content

When the replacement content has more audio tracks than the original content, broadpeak.io only matches the tracks that are present in the content source manifest. In the event that there is no language match, broadpeak.io uses a codec-compatible audio track with the "DEFAULT=YES" attribute as a match.

If we take a new example, where the original content contains a single audio rendition group with a single language, English (en), and the replacement content contains a single audio rendition group with two audio tracks, English (en) and Spanish (sp). Let's again assume for the sake of the example that both audio rendition groups are codec-compatible. Graphically, this would look like this:

982

In this example, since there is no Spanish audio track in the multivariant (i.e. main) manifest of the original content, broadpeak.io only matches English audio tracks together. The Spanish track will not be referenced in the output manifest.

491

3. Bandwidth compatibility of multiplexed audio and video variants

Once codec and language compatibility has successfully passed, the list of remaining possibilities for a match should be reduced. broadpeak.io now compares the bandwidth information of each variant in both manifests.

To preserve the best quality of experience, the system looks for the best variants from the replacement content to match to variants of the original content.

📘

Bandwidth as a guide

Bandwidth commonly is - for a same codec and profile - directly linked to encoding parameters such as resolution. Different assets encoded with the same parameters and resolution tend to result in the bitrate and therefore the same impact over the network bandwidth.

The variant of the replacement content - which is codec-compatible - that has the smallest difference in bandwidth with the variant of the original content is selected as a match.

Variant bandwidth is retrieved from the attribute BANDWITH on #EXT-X-STREAM-INF tag.

#EXT-X-STREAM-INF:BANDWIDTH=833000,AVERAGE-BANDWIDTH=758000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=426x240,FRAME-RATE=25,AUDIO="audio-aacl-63",CLOSED-CAPTIONS=NONE
replacementcontent-audio_63340_eng=63200-video=643600.m3u8

Use-case with more variants in the replacement content

In general, it is best to avoid a difference in the number of variants available between the original content manifest and the replacement content manifest. In the event that this happens, for instance replacing an SD channel with an HD channel, the scenario remains viable.

The expected behavior is that broadpeak.io's contextualization mechanism matches all compatible layers of the original content with the compatible replacement layers based on bandwidth, ignoring additional layers of the replacement content that do not have an equivalent in the original content. In fact, the variant(s) from the replacement content with the biggest difference in bandwidth is (are) dropped.

Let's take the following example in which we have two assets, an SD as original content and an HD as replacement content. They both share 3 layers with the same encoding profile.

SD (original):

  1. Resolution: 448x252 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 688000
  2. Resolution: 768x432 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 1427000
  3. Resolution: 1280x720 - Codecs: mp4a.40.2,avc1.640020 - Bandwidth: 2962000

HD (replacement):

  1. Resolution: 448x252 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 688000
  2. Resolution: 768x432 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 1427000
  3. Resolution: 1280x720 - Codecs: mp4a.40.2,avc1.640020 - Bandwidth: 2962000
  4. Resolution: 1280x720 - Codecs: mp4a.40.2,avc1.640020 - Bandwidth: 4884000

The 3 lowest variants of the SD content are matched to the 3 lowest variants of the HD content. The highest variant of the replacement content is dropped.

902

Use-case with fewer variants in the replacement content

Here as well, it is recommended to avoid this scenario and adapt the original and replacement streams to preserve quality of experience. If this is not possible, here is how broadpeak.io handles it:

broadpeak.io's contextualization mechanism tries to match all existing variants of the original content to the codec compatible variants of the replacement content which have the smallest difference in bandwidth. This way, a variant from the replacement content can become a match for several variants of the original content.

Let's take the following example where we have two assets, one HD as original content and an SD one as replacement content. They both share 3 layers with the same encoding profile.

SD (original):

  1. Resolution: 448x252 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 688000
  2. Resolution: 768x432 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 1427000
  3. Resolution: 1280x720 - Codecs: mp4a.40.2,avc1.640020 - Bandwidth: 2962000
  4. Resolution: 1280x720 - Codecs: mp4a.40.2,avc1.640020 - Bandwidth: 4884000

HD (replacement):

  1. Resolution: 448x252 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 688000
  2. Resolution: 768x432 - Codecs: mp4a.40.2,avc1.4D401E - Bandwidth: 1427000
  3. Resolution: 1280x720 - Codecs: mp4a.40.2,avc1.640020 - Bandwidth: 2962000

With a switch from the HD content to the SD content, the highest variant of the replacement content (720p) becomes a match for both 1080p and 720p variants of the original content.

904

Matching HLS variants with separate audio and video tracks

When working with separated audio and video tracks, things are more or less the same as with multiplexed audio and video variants, except that the compatibility check is applied on audio and video separately.

📘

Summary: separate HLS audio and video tracks

1.a Video Codecs. broadpeak.io looks at video CODECS compatibility between the video variant of the original and those of the replacement content. No codec compatibility = no contextualization
1.b Video Bandwidth. If there is codec compatibility, broadpeak.io looks at the BANDWIDTH value, and matches a video variant of the original content with the video variant of the replacement content that has the closest bandwidth value.
2.a Audio Codecs. broadpeak.io looks at the audio CODECS compatibility between the original and replacement content. No codec compatibility = no contextualization
2.b Audio Languages. broadpeak.io looks at LANGUAGE compatibility between audio variants of the original content and those of the replacement content. If the languages are different, variants with no correspondence in the replacement content are matched with the DEFAULT=YES compatible variant.

1.a Video Codec compatibility

broadpeak.io looks for compatibility between the variants of the original and replacement content. The solution parses codecs in the existing video variants of the original manifest, and attempts to find a compatible match with the codec in the replacement content manifest.

Codec information is retrieved from the attribute CODECS on the #EXT-X-STREAM-INF tag.

#EXT-X-STREAM-INF:BANDWIDTH=833000,AVERAGE-BANDWIDTH=758000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=426x240,FRAME-RATE=25,AUDIO="audio-aacl-63",CLOSED-CAPTIONS=NONE
replacementcontent-video=643600.m3u8

Even when audio and video are separated, the codec attribute in HLS often contains two values separated by a comma, which describes the audio and the video codecs of the track. The compatibility check is performed on video codecs at this stage.

Any video track that does not have a compatible match leads to a global incompatibility that results in a contextualization error. If all video tracks have a compatible match, the next compatibility rule applies.

1.b Video Bandwidth correspondence

To preserve the best quality of experience, the system looks for the best variants from the replacement content to match to variants of the original content.

broadpeak.io now compares the bandwidth information of each variant in both manifests.

📘

Bandwidth as a guide

Bandwidth commonly is - for a same codec and profile - directly linked to encoding parameters such as resolution. Different assets encoded with the same parameters and resolution tend to result in the bitrate and therefore the same impact over the network bandwidth.

The codec-compatible variant of the replacement content which has the smallest difference in bandwidth with the variant of the original content is selected as a match.

2.a Audio Codecs compatibility

When audio tracks are in dedicated variants, as is becoming more common (and a constraint when using fMP4/ISOBMFF), each audio variant of the original content must have a match with the replacement content. Similarly to the video, the audio codec is retrieved from the video variant #EXT-X-STREAM-INF.

In the example below, the first value before the coma in CODECS=\"mp4a.40.2,avc1.4D401F\ is the audio codec, which is valid for all audio tracks contained in the audio rendition group (declared with AUDIO="audio-aacl-63").

#EXT-X-STREAM-INF:BANDWIDTH=833000,AVERAGE-BANDWIDTH=758000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=426x240,FRAME-RATE=25,AUDIO="audio-aacl-63",CLOSED-CAPTIONS=NONE
replacementcontent-video=643600.m3u8

2.b Audio Language compatibility

The process to determine compatibility of audio languages when the HLS manifest uses separate video and audio tracks is the same as for multiplexed audio and video variants, explained in a previous section

If there is no exact language match, broadpeak.io attempts to match the audio tracks from the original content to the audio variant which has the DEFAULT=YES attribute within the audio group.

📘

Note

broadpeak.io does not maintain an ISO-639-1 to ISO-639-2 mapping table. Please make sure both original and replacement content use the same language code syntax or else it will be considered incompatible.

Matching HLS Subtitle variants

Similarly to what we have with audio languages, subtitles languages sometimes also differ between original and replacement content in Content Replacement applications. broadpeak.io performs compatibility checks in order to make sure formats are compatible and languages are properly matched.

  1. Format compatibility
    broadpeak.io does not perform any format checks. It is assumed that the subtitles used are WebVTT on both original and replacement content.

  2. Language compatibility
    broadpeak.io looks for the language of the subtitle variant(s) directly in the subtitle rendition group linked to the audio variant (indicated by SUBTITLES). In the example below, the subtitle rendition id is textstream.

# AUDIO groups
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio-aacl-63",NAME="English",LANGUAGE="eng",AUTOSELECT=YES,DEFAULT=YES,CHANNELS="2"

# Subtitle renditions
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="textstream",NAME="English",LANGUAGE="eng",AUTOSELECT=YES,DEFAULT=YES,URI="replacementcontent-textstream_7208961_eng=8000.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="textstream",NAME="Spanish",LANGUAGE="spa",AUTOSELECT=YES,URI="replacementcontent-textstream_12451841_spa=8000.m3u8"

# variants
#EXT-X-STREAM-INF:BANDWIDTH=833000,AVERAGE-BANDWIDTH=758000,CODECS="mp4a.40.2,avc1.4D401F",RESOLUTION=426x240,FRAME-RATE=25,AUDIO="audio-aacl-63",SUBTITLES="textstream",CLOSED-CAPTIONS=NONE
ARTE-audio_63340_eng=63200-video=643600.m3u8

# Audio renditions
#EXT-X-STREAM-INF:BANDWIDTH=83000,AVERAGE-BANDWIDTH=75000,CODECS="mp4a.40.2",AUDIO="audio-aacl-63",SUBTITLES="textstream"
ARTE-audio_63340_eng=63200.m3u8

The subtitle rendition group describes the encoding parameters of each subtitles variant available in the rendition group, including the language stated in the LANGUAGE attribute. The language value retrieved in the original content is compared to the language value retrieved in the replacement content to find a match for each subtitle variant.

If there is no match found, broadpeak.io's contextualization mechanism looks for the DEFAULT=YES subtitle track to perform a match. Therefore, languages might not be the same, but playback stability is preserved.

Matching HLS Key Frames

The same logic as for Video variant compatibility check is applied when working with Keyframe playlists (#EXT-X-I-FRAMES-ONLY). Since they do not have audio, languages compatibility checks are being bypassed.

  1. Codecs need to be compatible between the keyframe variants of the original content, and those of the replacement content.
  2. Keyframe variants are matched based on the smallest difference in bandwidth.

Referencing contextualized content

When all video, audio, subtitles and keyframes variants have been associated with a match, broadpeak.io can now manipulate manifests to reference the contextualized content(s). Original media references inside the master manifest are not modified - though some query parameters are added in the variant path.
Content replacement is referenced directly into each variant playlist, according to timing information defined by the slots.

Example of manifest for a media playlist with multiplexed audio and video tracks

#EXTM3U                                                                                                              
#EXT-X-VERSION:5
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:4
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T11:59:40.000000+00:00
#EXTINF:4, no desc
originalcontent-audio=129117-video=633990-01.ts
#EXTINF:4, no desc
originalcontent-audio=129117-video=633990-02.ts
#EXTINF:4, no desc
originalcontent-audio=129117-video=633990-03.ts
#EXTINF:4, no desc
originalcontent-audio=129117-video=633990-04.ts
#EXTINF:4, no desc
originalcontent-audio=129117-video=633990-05.ts
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T12:00:00.000000+00:00
#EXTINF:4, no desc
../../../../replacement_content/hls/replacementcontent-audio=129117-video=633990-190.ts
#EXTINF:4, no desc
../../../../replacement_content/hls/replacementcontent-audio=129117-video=633990-191.ts

Example of manifest for a media playlist with separate video track

#EXTM3U                                                                                                              
#EXT-X-VERSION:5
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:4
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T11:59:40.000000+00:00
#EXTINF:4, no desc
originalcontent-video=633990-01.ts
#EXTINF:4, no desc
originalcontent-video=633990-02.ts
#EXTINF:4, no desc
originalcontent-video=633990-03.ts
#EXTINF:4, no desc
originalcontent-video=633990-04.ts
#EXTINF:4, no desc
originalcontent-video=633990-05.ts
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T12:00:00.000000+00:00
#EXTINF:4, no desc
../../../../replacement_content/hls/originalcontent-video=633990-190.ts
#EXTINF:4, no desc
../../../../replacement_content/hls/originalcontent-video=633990-191.ts

Example of manifest for a media playlist with separate audio track

# English Audio track

#EXTM3U                                                                                                              
#EXT-X-VERSION:5
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:4
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T11:59:40.000000+00:00
#EXTINF:4, no desc
originalcontent-audio_eng=93375-01.aac
#EXTINF:4, no desc
originalcontent-audio_eng=93375_02.aac
#EXTINF:4, no desc
originalcontent-audio_eng=93375_03.aac
#EXTINF:4, no desc
originalcontent-audio_eng=93375_04.aac
#EXTINF:4, no desc
originalcontent-audio_eng=93375_05.aac
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T12:00:00.000000+00:00
#EXTINF:4, no desc
../../../../replacement_content/hls/replacementcontent-audio_eng=93375_190.aac
#EXTINF:4, no desc
../../../../replacement_content/hls/replacementcontent-audio_eng=93375_191.aac

Example of a manifest for a media playlist with separate audio track which matched a DEFAULT=YES english track

# Spanish Audio track

#EXTM3U                                                                                                              
#EXT-X-VERSION:5
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:4
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T11:59:40.000000+00:00
#EXTINF:4, no desc
originalcontent-audio_spa=93375-01.aac
#EXTINF:4, no desc
originalcontent-audio_spa=93375_02.aac
#EXTINF:4, no desc
originalcontent-audio_spa=93375_03.aac
#EXTINF:4, no desc
originalcontent-audio_spa=93375_04.aac
#EXTINF:4, no desc
originalcontent-audio_spa=93375_05.aac
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2022-11-10T12:00:00.000000+00:00
#EXTINF:4, no desc
../../../../replacement_content/hls/replacementcontent-audio_eng=93375_190.aac
#EXTINF:4, no desc
../../../../replacement_content/hls/replacementcontent-audio_eng=93375_191.aac

Contextualisation failure

By default, incompatible original content and replacement content prevent the contextualization process to succeed, resulting in the content in the original manifest not being replaced.

This means that a video, audio, keyframe or subtitle variant of the original content does not have a compatible match in the replacement content. This may be due to codec incompatibilities or a language incompatibility between the variant(s) of the two manifests, as highlighted in the matching rules above.

Below is a short list of events which can lead to a contextualisation failure, for ease of troubleshooting:

  • There is codec incompatibility at the level of the video or audio. In the event of multiplexed audio and audio variant, both audio and audio codecs of the variant must match in both manifests. When using separate audio and audio variants, codecs of the video variant must match between both manifests, and audio codecs of the audio group rendition attached to the video variant must also match.
  • There is a language incompatibility on audio between both manifests. The language must match in both manifests, or with the first codec-compatible default track set in the replacement content manifest.
  • The original and replacement sources do not use the same audio or subtitle language code (ISO-639-1 vs ISO-639-2)
  • For Dynamic Ad Insertion applications, the VAST response does not contain compatible creative. If you are using a Transcoding Service, MediaFiles must be MP4 or Mezz type. Without Transcoding Service, it is expected that the MediaFiles must reference m3u8 or mpd files.

If you have any issue that persists and the suggestions above do not work, we invite you to validate the stream requirements in the related section: Input Streaming Formats and to check the troubleshooting section Troubleshooting.

Contact us at [email protected] if the issue persists and the documentation does not help.

Working with Ad Server Tags

When defining an Ad Server as Source in broadpeak.io, it is necessary to set an Ad Tag (i.e. URL) which will allow the system to interrogate the Ad Server. The Ad tag contains placeholders (usually referred to as Macros) that broadpeak.io will replace with real values when requesting the Ad server.

The Tag and the necessary Macros will be provided to you by the Ad Technology partner that acts as Ad server or SSP.

Using Macros

When defined an Ad Server as source, you are given the possibility to enter the Ad Tag coming from the Ad Technology provider of your choice. You can enter a URL and some query parameters also called Macros.

Part of the concept of targeting requires the Ad Technology provider to retrieve dynamic values so personalization can be best achieved. This is done through the use of these Macros.

System values

Some values can be retrieved from the system directly:

  • Cachebuster value: $MMVAR_CACHE_BUSTER
  • Client IP: $MAP_REMOTE_ADDR
  • Signal ID: $_MMVAR_LIVEAR_SIGNALID
  • Live break duration in seconds: $_MMVAR_LIVEAR_SLOTDURATION
  • Live break duration in ms: ${_MMVAR_LIVEAR_SLOTDURATION}000

Example

?max_pod_duration=$_MMVAR_LIVEAR_SLOTDURATION&cb=$MMVAR_CACHE_BUSTER&ip=$MAP_REMOTE_ADDR

or

?pmxd=${_MMVAR_LIVEAR_SLOTDURATION}000&cb=$MMVAR_CACHE_BUSTER

Values from the Client Request

Some values can be directly retrieved from the client/CDN request query parameters or headers.

HTTP Headers

By default, the following headers are forwarded from the Client/CDN request to the Ad Server:

  • X-Forwarded-For: the client IP can be retrieved from here if the CDN is configured to pass it over.
  • User-Agent: the user-agent of the device if provided by the CDN in the request.

When defining the Ad Server configuration, it is possible to map the information received in the Client/CDN request as a header into Macro values to pass onto the defined Ad Server tag.

For that, you simply need to add a Macro with the header name, starting with $http_.

Note

If you need to retrieve the value of the header User-Agent in the client/CDN request and pass it to the Ad Server with the Macro ua (a fairly common one used by many Ad Server and recommended by the IAB), the behavior is a bit different. In that case, the Ad Server configuration should contain the following query parameter:

ua=$http_user_agent

Query Parameters

When defining the Ad Server configuration, it is possible to map the information received in the Client/CDN request as a query parameter into Macro values to pass onto the defined Ad Server Tag.

For that, you simply need to add a Macro with the parameter key name, starting with $arg_

Example

We need to retrieve the value of the query parameter user received in the client/CDN request URL (as &user=...) and pass it to the Ad Server with query parameter "uid". The Ad Server configuration should contain the following query parameter:

uid=$arg_user

Ad Reporting

Monetisation only happens when Impressions are tracked.

Client Side Ad Tracking

Tracking on broadpeak.io is supported through a proprietary library which enables unified tracking for HLS and DASH on the client. The library is developed in numerous languages for different platform and allows:

  • Impression tracking (start, impression, 25%, 50%, 75%, complete)
  • provide ad-skipping policies if defined at the campaign level.
  • provide for each break, the number of Ad per break, the duration of each Ad, the index of Ad inside the break, and the position of the Ad.
  • provide functions to retrieve timed based information such as bookmarks, chapters, etc...

This Library must be implemented by the client application and is already integrated with major players including native players.

More info can be found on the Smartlib Online Documentation

Some Player sample integrated with Smartlib are also available on Github

📘

Contact us through the Live chat or [email protected] to have access to the tracking library.

Server Side Ad Tracking

Server-side Ad Tracking can be enabled on Ad Insertion type of Services, by activating the checkbox in the second menu, called Enable server-side ad tracking.

broadpeak.io will perform tracking by calling the beacons provided in the VAST answer, in accordance with the way the Ad is being consumed by the player. Supported beacons are the following events:

  • Impression
  • Start
  • 25%
  • 50%
  • 75%
  • Complete

🚧

SSAT Limitations

  • Server Side Ad Tracking is currently not compatible with Client Side Ad Tracking on a same Service.

Media Segment Availability check

When working with Server Side Ad Tracking, broadpeak.io allows to activate a feature which validates the availability of the Ad media segments before triggering a beacon call. It is an optional feature which will prevent reporting Impressions when the Ad content is not available.

With this option enabled, broadpeak.io performs a HTTP HEAD on each Ad media segments requested. Tracking beacons will be triggered only if all the Ad media segments that represent the quartile in question are available. An Ad media segment is considered available if the response from the HTTP HEAD is 200.

Transcoding logic

Ad creative transcoding is activated by default in broadpeak.io when a Transcoding Service is associated with the Ad Insertion Service.

If the VAST response contains a MediaFile of type "mezz" or "mp4", the transcoding flow will be triggered. If the VAST response contains other types of MediaFiles, the transcoding flow will not be triggered.

The insertion will not be performed in the cases where the VAST answer does not contain any compatible MediaFile.

Creating a Transcoding Service in broadpeak.io

Transcoding Services definition

It is not currently possible to define a Transcoding Service by yourself. Please reach out to us via your direct CSM contact or via the live chat.

Transcoding consideration period

The first time a creative is returned in the VAST response under a compatible MediaFile, a transcoded job is created to prepare the creative for HLS or DASH delivery. Depending on the transcoding profiles configured and the duration of the creative, this process may take more or less time.

The creative will only be inserted into a Manifest when the transcoded jobs is over, and ready to be packaged for HLS or DASH delivery through JITP.

Transcoded Ad retention

By default, transcoded creative are stored for 1 month in broadpeak.io.
Origin HTTP Cache-Control header is set to max-age 3600 seconds.

Supported Containers & Codecs

Video Codecs

  • H.264 / AVC1 (ISO/IEC 14496-10)
  • H.265 / HEVC (ISO/IEC 23008-2)

Video Containers

  • MP4 (fmp4) (DASH)
  • TS (HLS)

Audio Codecs

  • AAC / MPEG 4-AAC (LC, HE) (ISO/IEC 14496-3)

Context management

In Live streaming applications, we usually observe that players request new manifests every three media segments. When the packager updates the manifest, it must keep consistency with the previous manifest so that the player can keep track of the media that is added.

Performing manifest manipulation on Live streams requires keeping the same level of consistency, and therefore being able to manage contextual information for each streaming session started by a player.

Session ID

To identify a session, broadpeak.io relies on a unique parameter called the sessionid. This is a unique value generated by the platform on the first request coming from the player, and it identifies a unique session. The system keeps contextual information related to this sessionid, and therefore all the following manifest requests from the player must contain the generated sessionid.

A manifest request without sessionid will be interpreted as a new session with no previous context, and will be assigned a new sessionid value.

Query Parameter

By default, the system will generate a sessionid value for all manifest requests that come without a sessionid query parameter. It will then respond with an HTTP 307 Temporary Redirect to a new URL made of the concatenation of the manifest path of the initial request, the sessionid query parameter and other query parameters needed by the system.

curl -i -L https://stream.broadpeak.io/d3d9446802a/myStream/myOutput/index.mpd?zipcode=25267
HTTP/2 307
location: /myStream/myOutput/index.mpd?zipcode=25267&serviceid=d3d9446802a&sessionid=10d0e55a246-f8c09588-c798-4890-a4b7-54155d02b742

The figure below shows a sequence diagram of session creation between the client (player), the CDN and broadpeak.io. To simplify, we are using building blocks, but a CDN might be built with several nodes.

📘

Note

In addition to the sessionid query parameter, the system also adds a serviceid query parameter repeating the portion of the path immediately after the domain name (FQDN) of the request. That value is also removed from the path.

HTTP GET https:/stream.broadpeak.io/d3d9446802a/myStream/myOutput/index.mpd?zipcode=25267
< HTTP 307 Location: /myStream/myOutput/index.mpd?zipcode=25267&serviceid=d3d9446802a&sessionid=x

Header

In the event you use Broadpeak on-premise CDN, it is possible to rely on the CDN functionality which generates the sessionid itself, and pass it to broadpeak.io in the request via specific headers. In this scenario, broadpeak.io will not generate the sessionid value and will respond with a an HTTP 200 and the contextualized manifest directly in the body. This scenario is not enabled by default.

Contact us directly or your Broadpeak representative for more information.