Dynamic Ad Insertion with Akamai AMD

How to configure Akamai as a CDN for Dynamic Ad Insertion applications

In Using broadpeak.io with a CDN we explain the reasons why you need to use a CDN in front of your broadpeak.io services in order to deliver your manipulated streams in the most optimal and efficient way.

In this playbook, we'll look at a couple of examples and illustrate how to configure it with the Akamai Adaptive Media Delivery product, for a Dynamic Ad Insertion application (whether pre-roll, live ad replacement, or AVOD).

Prerequisites

You need to be familiar with how to configure a broadpeak.io Dynamic Ad Insertion service first. You'll find other playbooks in the "Getting Started" section of our documentation, as well as in the present "Playbooks" section. For expediency, the examples in this playbook will use the same sources as those Getting Started articles.

You also need to ensure that your Akamai account has access to the Adaptive Media Delivery product. Talk to your Akamai account manager to enable it.

Rules

The primary aspect of configuration for the CDN relates to routing. In an ABR stream, there are one or multiple manifests or playlists, and multiple media segments that the player will request in order to render the stream. The player connects to a single CDN, which needs to know where to send those requests. So it needs to be given a set of rules to follow. Those rules will be somewhat dependent on the type of service you are implementing.

For a Dynamic Ad Insertion service, you will need at the very least:

  • Rules that define how to direct manifest requests to broadpeak.io
  • Rules that define how to direct segment calls for the original content stream to its origin (ie. the server that stores that original packaged content)
  • Rules that define how to direct segment calls for ads

Step 1 - Property

The first thing you need to do is to set up a Property in the Akamai CDN solution.

  • Go to CDN > Properties in the Control Center sidebar
  • Click the + New Property button, and choose Adaptive Media Delivery in the next screen.

You will be presented with a wizard to configure that product.

  • Set the Property name to anything that is easily identifiable later, such as the target hostname. Select the latest Rule Format.

You now land on the screen in which you can configure the property.

🚧

Minimum functional configuration

There are dozens of settings that can be defined with Akamai CDN. It's not the role of this playbook to explain them all. We'll concentrate on the minimum set to successfully define a working example with the samples that we provide for tests.

Some of the settings (in particular caching rules, TTL, TLS version, etc.) may also need adjusting based on your own Origin servers and typical CDN configuration needs.

Note also that the example concentrates on browser-based streaming into common web video players. Other players may require additional and specific settings.

If something isn't behaving as expected, don't hesitate to contact our Support staff at [email protected].

For this playbook, we will make use of the fact that Akamai offers a pre-configured akamaized.net domain name, removing the need to configure a hostname.

  • In the Property Version Information panel, select "Shared Cert" under Security Options. It's the easiest way to ensure we can use HTTPS for delivery of the content in this playbook
  • In the Property Hostnames panel, click the + Hostnames button and select Add Shared Certificate Hostname
  • In the popup that appears, set Edge Hostname to a hostname of your choice.
    • For Segmented Media Mode, choose Live or VOD depending on what you want to deliver. Here we're looking at Live Pre-Roll, so we will choose Live

We are now ready to start on the configuration of the routing. We'll use <https://origin.broadpeak.io/bpk-tv/bpkiofficial/hlsv3/index.m3u8> (one of our default samples) as the source, from which - in this case - a Live Pre-Roll service has been created, the URL of which would look like https://stream.broadpeak.io/a3eb043e7bf775ded159a8940be5e720/bpk-tv/bpkiofficial/hlsv3/index.m3u8.

Step 2 - Default Rule

The Default Rule defines the behavior that applies to all requests, unless any other rule applies - which we will configure later. It could be seen as the fallback. We will use it to configure to deliver the content segments

  • Scroll until you see the Property Configuration Settings panel.

  • Select the Default Rule in the left hand sidebar, and look at the Behaviors panel.

  • Under Origin Server set Origin Type to "Your Origin", and then

    • Set Origin Server Hostname to the hostname of the origin that contains your live content. In this playbook it is origin.broadpeak.io
    • Set the Forward Host Header to "Origin Hostname"

  • Under Content Provider Code, you need to choose a CP code (which is used in the Akamai realm to identify usage, reporting and billing segments). Click Create new... if you don't have one yet, or need a separate one.

  • Under Segment Media Deliver Mode, choose the same mode as configured in the property ("LIVE" in this case)

  • Under Content Characteristics, ensure that HLS and DASH are enabled. You can switch off HDS and Smooth

  • All other settings can be left at their default for this playbook. Check the Akamai configuration if you want to know more about them.

We now need to also configure caching. We want all those content segments to be cached in the Akamai network, for efficient delivery

  • At the bottom of the Property Configuration Settings panel, click + Behavior, and select Standard property behavior
  • In the popup, find or type Caching in the left-hand panel and click Insert Behavior
  • Here the actual configuration will depend on your content origin. Under Caching option, we will just have a bare-bones setting that forces cache of that content for one day.

📘

Note that In a production system, it's likely that your origin will define the behavior already, and you will therefore want to choose "Honor origin Cache-Control and Expires".

That should do it. Press Save.

At this stage, you may want to activate this first version, just to validate that you have the basics right.

Deploy your property

Scroll back to the top of the page and select the Activate tab.

Akamai allows you (and strongly recommends) to deploy your property onto a Staging Network. Doing so will make it available on a small network of edge servers. It is also faster to deploy. To test it is however a bit more complex, as you likely will need to spoof hostnames on your local machines. It is beyond the scope of this document to explain it, and there is a lot of documentation on the Akamai site.

In this playbook, we will just deploy to the production network directly.

  • Click Activate v1 on Production
  • In the popup screen, after checking whether any of the Warning messages apply to your test, click Activate v1 on Production again.
  • You will now have to wait a few minutes for the deployment to be done. The screen will provide you with visual progress and confirmation, and you should also receive an email.

When deployment is done, you should be able to play back the stream through your chosen hostname, in our case https://bpkio-cs-akamai-playbook-test.akamaized.net/bpk-tv/bpkiofficial/hlsv3/index.m3u8. Use any of your standard web players to perform that test.


Step 3 - Manifests

So far all we've really done is to create a way to distribute and cache the live stream through the Akamai Network. We now need to define how to redirect calls for manifests and send them to broadpeak.io.

  • If needed, go back to your property and choose Edit New Version, to create a v2 version on top of the work done so far.
  • In the Property Configuration Settings click + Rules in the left sidebar. Choose a blank rule and name it "Manifests".
  • Back in the main screen, in the Criteria panel, you define when the rule applies. We want Akamai to follow it when it comes to delivering HLS and DASH manifests. In most cases, that can be determined based on file extensions
  • Under Behaviors > Origin Server, set Origin Server Hostname to stream.broadpeak.io and Forward Host Header to "Origin Hostname"
  • When it comes to caching we want to ensure that no caching is done for those manipulated manifests. Add a Caching behavior and set the Caching option to "No store"

📘

Enabling SmartLib

If you are using (or planning to use) SmartLib SDK on the client side, you need to also add a behavior at this point, which exposes the Location header so that the SDK can make use of it in its control logic

  • Press Save

Step 4 - Ads

So far so good, but now we want to handle the inserted ads. When you configure a broadpeak.io Dynamic Ad Insertion service, there will be segments for ads referenced in the manifest, which will most likely come from different origins.

How you go about it depends on whether you are using broadpeak.io to process your ads or not.

Ads prepared by broadpeak.io

If you use broadpeak.io for ad insertion, and use the transcoding feature, broadpeak.io will originate the prepared ads through stream.broadpeak.io. In this case, the path to the prepared content will start with /bpkio-jitt/.

For example, the stream output with a short pre-roll might look like the following:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA-SEQUENCE:1
#EXT-X-TARGETDURATION:8
#EXT-X-PROGRAM-DATE-TIME:2023-10-03T20:14:17.821796+00:00
#EXT-X-DISCONTINUITY
#EXTINF:3, no desc
../../../bpkio-jitt/profile_15_950_91602f30ed840401/b4e039d1af7958020bc7603ac31c639e/b4e039d1af7958020bc7603ac31c639e.ism/b4e039d1af7958020bc7603ac31c639e-audio=128000-video=1600000-1.ts/bpk-sst/ClEKTzliZjMxYzdmZjA2MjkzNmFiODNhMTkwNDYwYjUwYzc0OjEwYTBiMzNhNi0zNWE1MzY5YS0yMmZiLTQ5MTAtYjJjOC1kYzdjMDMzMGRmOTQSXgpcOWJmMzFjN2ZmMDYyOTM2YWI4M2ExOTA0NjBiNTBjNzQ6MTBhMGIzM2E2LTM1YTUzNjlhLTIyZmItNDkxMC1iMmM4LWRjN2MwMzMwZGY5NDpzbG90OnByZXJvbGw?bpkio_serviceid=a3eb043e7bf775ded159a8940be5e720&bpkio_sessionid=10c0b51d66-005aea96-dc0b-40d4-8004-090bc0949313
#EXTINF:3, no desc
../../../bpkio-jitt/profile_15_950_91602f30ed840401/b4e039d1af7958020bc7603ac31c639e/b4e039d1af7958020bc7603ac31c639e.ism/b4e039d1af7958020bc7603ac31c639e-audio=128000-video=1600000-2.ts/bpk-sst/ClEKTzliZjMxYzdmZjA2MjkzNmFiODNhMTkwNDYwYjUwYzc0OjEwYTBiMzNhNi0zNWE1MzY5YS0yMmZiLTQ5MTAtYjJjOC1kYzdjMDMzMGRmOTQSXgpcOWJmMzFjN2ZmMDYyOTM2YWI4M2ExOTA0NjBiNTBjNzQ6MTBhMGIzM2E2LTM1YTUzNjlhLTIyZmItNDkxMC1iMmM4LWRjN2MwMzMwZGY5NDpzbG90OnByZXJvbGw?bpkio_serviceid=a3eb043e7bf775ded159a8940be5e720&bpkio_sessionid=10c0b51d66-005aea96-dc0b-40d4-8004-090bc0949313
#EXT-X-PROGRAM-DATE-TIME:2023-10-03T20:14:23.000000+00:00
#EXTINF:4, no desc
live-audio=126470-video=1600215-424091019.ts?bpkio_serviceid=a3eb043e7bf775ded159a8940be5e720&bpkio_sessionid=10c0b51d66-005aea96-dc0b-40d4-8004-090bc0949313
#EXTINF:4, no desc
live-audio=126470-video=1600215-424091020.ts?bpkio_serviceid=a3eb043e7bf775ded159a8940be5e720&bpkio_sessionid=10c0b51d66-005aea96-dc0b-40d4-8004-090bc0949313

This means that requests for media segments of the alternate content are sent to https://[your-hostname]/akamaized.net/bpkio-jitt/...

Extending your property configuration to cover for this is an extension of the work done so far: we just need to add a behavior to route requests for the ad segments towards the same stream.broadpeak.io origin, based on the path of the request.

  • Criteria: If Path matches one of /bpkio-jitt/*
  • Origin Server Hostname: stream.broadpeak.io
  • Forward Host Header: "Origin Hostname"

However, unlike requests for manifests (which go to the same origin), we need to configured the CDN to cache those requests. So, when it comes to adding the Caching behavior:

  • Caching option: "Cache"
  • Max age: 1 day (or whatever fits your requirements)

Pre-packaged Ads

If you don't use the broadpeak.io's transcoding solution, and instead have ads coming pre-packaged and from a different origin, you will need to add a new rule that matches the corresponding path and redirects to that origin.

For example if the ads come from <https://my-ad-origin.server.com/packaged_ads/>... you will need a new rule with appropriate criteria and behavior:

  • Criteria: If Path matches one of /packaged_ads/*
  • Origin: my-ad-origin.server.com
  • Caching option: "Cache"

 Other optional rules

Depending on your application, there may be other redirection rules that you need to apply. Some of the common ones are:

Slates

If you are using slates (typically in a Live Ad Replacement scenario), and you have them transcoded and packaged by broadpeak.io, the same rule illustrated above for ad segments will take care of redirecting requests for segments of the slate.

If instead you use a pre-packaged asset, you will need to add a specific rule (potentially) in the same way as illustrated above for pre-packaged ads.

SSAT

If you do not use broadpeak.io to transcode your ads, and you enable SSAT, broadpeak.io will proxy requests to the relevant ad segments (via stream.broadpeak.io again). The path starts with bpk-sst.

Once again, an additional behavior can be created for that use case, and those requests cannot be cached:

  • Criteria: If Path matches one of */bpk-sst/*
  • Origin Server: stream.broadpeak.io
  • Caching options: "No store"

You need to make sure that this rule applies before the rule that matches /bpkio-jitt, since the SSAT call contains that path part as well. The SSAT call needs to happen first, and it redirects to a new URL that still contains / bpkio-jitt but without the bpk-sst sub-path.

 HLS Subtitles

If your content is in HLS and has WebVTT subtitles, but the alternate content (replacement content, or ads) does not, broadpeak.io will insert references to an empty VTT file (/empty.webvtt).

You need to add this one to your distribution as well:

  • Criteria: If Path matches one of /empty.webvtt
  • Origin Server: stream.broadpeak.io
  • Caching options: "Cache"

 Final Step

For an initial configuration, this ought to do it.

It is now time to activate this new version of the property. After that, you should be able to stream your content, simply by replacing the stream.broadpeak.io part in your service URL with the Akamai AMD hostname you selected.

You can even test this in the WebApp, in the preview page for your service