May 5, 2021

How to deliver improved VOD experiences with Verizon Media Smartstart™

By Anna Katharina Reykowski, Sr. Product Manager, Verizon Media

OTT video monetization has become an important revenue stream for content owners. So it’s not surprising that pressure is increasing to make the most out of every monetization opportunity. One example of this is the generation of revenue from VOD libraries.

VOD manifests come with unique challenges. The HLS specification (RFC 8216) requires that VOD manifests are delivered in their entirety upon the initial playback request, and the manifests may not be altered afterward.

This means that all ad breaks must be filled up front when the initial playback request is made from the video player. Depending on the content, the number of ads can be substantial, and it can take ad servers a long time to return a response. Until the ad server’s response is received, the manifest server cannot respond back to the requesting client with the fully formed manifest. This can create a negative viewer experience, as increases to content start time are directly correlated to the number of ad breaks.

Compare this with linear streams, where manifests contain a small video window and are updated every few seconds. With live manifests, ads are retrieved one ad break at a time, guaranteeing fast start-up times and avoiding unnecessary depletion of ad inventories.

To address the above challenges, we have developed Verizon Media Smartstart™, a new capability that returns VOD assets as linear streams. Smartstart enables you to maximize your monetization opportunities without negatively impacting the viewer experience.

With the Smartstart APIs you:

  • Can convert any VOD asset within your Verizon Media Platform content library to a Smartstart asset
  • Do not need to re-encode or increase your storage usage 
  • Can create a “linear” streaming version of your VOD asset while leaving your existing VOD asset intact
  • Can utilize metadata enriched manifests to preserve the look and feel of VOD playback on the player side even while playing linear streams

Continue reading to learn how to enable a Smartstart asset within your VOD library, play it back, and update your video player to guarantee the same VOD-like playback experience viewers enjoy with regular VOD assets.

Enabling a Smartstart asset

In this example, we first make a POST request to the Smartstart API to define a new Smartstart asset in the system using the existing VOD asset. Our sample asset’s GUID or asset ID is e2f25c7407474386b0ae35c34490c450.

Each ad break in the Smartstart asset will have a defined ad break duration of 60 seconds, as defined via  beam_break_duration. This duration will be sent to the ad server for each ad break request. Note that the total duration of ads returned by the ad server may be greater or less than the requested duration.

Once we have defined this asset, we need to combine all our URL parameters to create a signature. Be sure to include your API key and Uplynk account owner ID so that a valid signature can be computed. In our example, we are also defining the ad server configuration we want to use ('my_ad_config'),  adding dynamic manifest markers for a top-level timeline, and ad break information. We will cover dynamic manifest markers in more detail later in this article.

Once the POST request is made, the system returns a playlist ID. We use this ID to create a full playback URL.

The sample script below is of the full playback URL for a DASH manifest. It can easily be altered to print out an HLS playback URL by replacing mpd with m3u8. We will stick with DASH for this example, as DASH manifests are more human readable than their HLS counterparts.

import json
import requests
import hashlib, time, hmac, urllib.parse, random
from api_auth import APICredentials, APIParams
 
class LinearPlaylistAPI:
    def __init__(self):
        self.host = "http://services.uplynk.com"
     
    def run(self):
        self._create_linear_playlist()
     
    def _create_linear_playlist(self):
        url = "{}{}".format(self.host, "/api/v4/linear-playlist/")
         
        description = "My Smartstart Asset" # Brief description.
        beam_break_duration = 60
        playlist = [
            {
                "beam":{
                    "id":"e2f25c7407474386b0ae35c34490c450"
                }
            }
        ]
        payload = {
            'desc': description,
            'beam_break_duration': beam_break_duration,
            'playlist': playlist
        }
        headers = {'Content-Type': 'application/json'}
        response = requests.post(
            url, params=APIParams(APICredentials()).get_params({}), data=json.dumps(payload), headers=headers
        )
         
        # print(response.json())
        jsonResponse = response.json()
        print("Smartstart ID: ")
        print(jsonResponse["id"])
        playlist_id = jsonResponse["id"]
         
        # inputs
        apiKey = '1234567890abcdefghijklmnopqrstuvwxyz1234' # from the CMS UI
         
        # combine all of the parameters except the signature
        queryStr = urllib.parse.urlencode(dict(
            exp = int(time.time()) + 60, # expire 60 seconds from now
            rn = str(random.randint(0, 2**32)), # random number
            ct = 'p', # sets content type to playlist
            cid = playlist_id, # the playlist / Smartstart ID
            oid = '1234567890abcdefghijklmnopqrstu', # uplynk account owner ID
            ad = 'my_ad_config' # the ad configuration to be used
        ))
         
        # compute the signature and add it to the *end*
        queryStr = queryStr + '&dmm.schema.top=timeline&dmm.schemas.breaks=break_info'
        sig = hmac.new(apiKey.encode('utf-8'), queryStr.encode('utf-8'), hashlib.sha256).hexdigest()
        queryStr = queryStr + '&sig=' + sig
         
        # Add the query string to the playback URL.
        url = 'https://content.uplynk.com/playlist/'
        url = url + playlist_id + '.mpd?' + queryStr
        print("DASH playback URL: ")
        print(url)
         
LinearPlaylistAPI().run()

You can also download our sample Docker Container with supporting CRUD operations from our GitHub account.

Player integration

Now that we have our playback URL, it is time to play it back in our player of choice. You will notice that players will not automatically render a scrub bar because the VOD asset is returned as a linear stream. Of course, scrub bars and ad break indicators are desirable for VOD playback. As mentioned earlier, we are enhancing the manifest with dynamic manifest markers. We can now use those markers to parse out information that the video player can use to draw a scrub bar and ad break indicators.

The URL parameter dmm.schema.top=timeline adds a dynamic manifest marker at the top of the manifest that includes information about the content duration and the location of each ad break within the asset (ad break locations are defined during ingest time). In our example, the content duration is 888.032 seconds, and the ad breaks are located at 103.125, 148.667, 349.792, 437.208, 472.083, 678.833, and 744.083 seconds. In DASH, this data is accessible via EventStream:*

<EventStream schemeIdUri="urn:uplynk:top-data:timeline" timescale="90000" value="top-data">
<Event duration="80010000" id="80010000" presentationTime="0">
{"breaks":[
{"id":1,"offset":103.125},
{"id":2,"offset":148.667},
{"id":3,"offset":349.792},
{"id":4,"offset":437.208},
{"id":5,"offset":472.083},
{"id":6,"offset":678.833},
{"id":7,"offset":744.083}],
"breaks_count":7,
"content_duration":888.032,
"repeat":0,
"session_id":"a4a905ce2f194204a11ce87c59d3a9b3"}
</Event>
</EventStream>

NOTE: In HLS, this dynamic manifest marker is added in an #EXT-X-DATERANGE tag at the top of the ray manifests, with a CLASS="urn:uplynk:top-data:playlist:v1".

Since ads will be fetched on-demand, as playback approaches an ad break (as opposed to upfront when the manifest is first requested), actual ad break information will not be immediately known when playback starts. Because of this, we recommend indicating ad breaks as dot-like markers on the timeline. To provide countdowns and other desired information whenever an ad break occurs, we need to know details about each ad break as it becomes available. We can easily include this information in the manifest through the URL parameter  dmm.schemas.breaks=break_info.

When this parameter is added, the following details are included in the manifest for each ad break:

  • Length of current ad break (as requested or open-ended)
  • Length of current ad break (actual)
  • Duration of current ad
  • Number of ads in the ad break 
  • Index of current ad (i.e., which ad within the ad break)
  • Offset of current ad with the ad break (in seconds)
  • Ad break index (i.e., which ad break within the stream)
  • Identify ad slate (in the case of Smartstart, no ad slate is inserted, so this will always be ‘0’)
  • Identify if ad break information is ready (i.e., received from ad server and processed)

In our DASH sample, an example of a break_info Dynamic Manifest Marker looks like this:

<EventStream schemeIdUri="urn:uplynk:ad-data:break_info" timescale="90000" value="ad-data">
<Event duration="2695680" id="16098750" presentationTime="0">
{"ad_dur":29.952000000000012,
"ad_index":0,
"ad_offset":0.0,
"ad_slate":0,
"break_dur_act":60.160000000000025,
"break_dur_req":60.00,
"break_index":0,
"dmm_data_not_ready":0,
"num_ads":2}
</Event>
</EventStream>

This marker tells us that we are looking at the first ad within the first break. A total of two ads will fill the ad break. The current ad is just under 30 seconds long (29.952000000000012 seconds to be precise). And while the requested break duration was 60 seconds, the actual break duration will be slightly higher (60.160000000000025 seconds). 

Now that this information is available, the video client can parse it for ad breaks as desired.

Lastly, we need to enable seeking to create a full VOD-like experience. For this, you can use the plts URL parameter. The plts value is a time expressed in seconds that is relative to the playlist. For ease of use, the plts parameter is excluded from the URL token signature.

In this example, https://content.uplynk.com/playlist/[Playlist UUID][.mpd | .m3u8]?plts=12 will seek 12 seconds into the Smartstart asset. Note that only content slices are taken into account when seeking in a Smartstart asset. Ad breaks are excluded from the calculation. 

It takes only a few steps to parse the manifest metadata to render a scrub bar on the video player, add ad break indicators, display ad break information and support scrubbing throughout your linear VOD asset. 

We also offer an out-of-the-box integration through our video player partner THEOplayer for anyone who prefers a more hands-off approach.

Conclusion

Smartstart is another way Verizon Media helps you get more value out of your content library while delighting your viewers with fast start-up times and engaging experiences that drive monetization. Smartstart, along with Smartplay, helps maximize your content's monetization potential, delivers personalized ad experiences, and provides attribution via server-side beaconing.  

We’ve made it easy to enable Smartstart. Integrate it and use it with your player solution, or take advantage of our pre-integrated solution with our player partner THEO Technologies.

Reach out to your account manager or contact us if you have any questions about Smartstart.

Contact us

Sales

Support

Manage your account or get tools and information.

More info