SERVERSIDE.AI
  • Welcome to serverside.ai
  • Getting Started
    • Prerequisites
    • Onboarding Guide
      • Serverside.ai: Create an account
      • Prepare content source
        • Encoding specification
        • Packaging specification
        • Ad-Marker specification
          • SSAI LIVE - SCTE35
          • SSAI VoD - AdCuePoints
      • Request SSAI enabled stream
    • Features
  • Content Source
    • Encoding
    • Packaging
      • HLS
      • DASH
    • Protection
    • Ad-Marker Specifications
  • Video Player/App
    • Live - DASH/HLS
    • VOD - DASH/HLS
    • VAST Tracking
      • Live - DASH
      • Live - HLS
      • VOD - DASH/HLS
      • ClientSideTracking SDK
    • Timeshift/Startover for LIVE
    • Playlist size for LIVE
    • PauseLiveTV
  • Ad-Server Integration
    • Ad-Server Parameter
      • Equativ/ SmartAdServer
      • Freewheel
      • Google Ad Manager
      • SpotX
    • GVA - Generic VAST Adapter
      • GVA - Configuration
    • 3rd Party Audience Data Integration/DMP
  • Ad Media Condition and Delivery
    • Ad Media - Origin integration
    • Ad Media - CDN integration
    • Prefetch API
  • Manual - User Interface
    • Account
    • Channels/Streams
    • Reports
    • Assets
  • REST API
    • Channels
      • API routes - Channels
      • VOD Channels
      • Detailed channel analysis errors
    • Reports
      • API Routes - reports
    • Playlists
    • Error responses for all routes
    • Further Documentation
  • Support
    • About support case management
    • Creating a case
    • Case language
    • Case processing
    • Booking a meeting
    • Requesting elevated attention
    • Closing a case
  • FAQ - Questionnaire - Glossary
    • Q&A
    • Questionnaire
    • Glossary
    • Files
  • Quality of Service
  • Release Notes
    • Version 2.1.0.x
    • Version 2.0.7.x
    • Version 2.0.6.x
    • Version 2.0.5.x
Powered by GitBook
On this page
  • Differences to DASH
  • Option 1: Player has no API to retrieve segments
  • 1. Manifest API Request
  • 2. Starting Playback
  • 3. Load-VAST data
  • 4. Detect the start of an ad in the stream
  • 5. Keep track of the ad playback and send beacons
  • Option 2: Player has an API to retrieve segments
  • 1. Manifest API Request
  • 2. Fetching the Master Manifest
  • 3. Load-VAST data
  • 4. Detect the start of an ad in the stream
  • 5. Keep track of the ad playback and send beacons
  • Example integration of Option 2
  1. Video Player/App
  2. VAST Tracking

Live - HLS

PreviousLive - DASHNextVOD - DASH/HLS

Last updated 1 year ago

As in the example the HLS example follows five steps to completely implement VAST tracking client side.

There are two ways to integrate Live - HLS VAST tracking depending on the capabilities of the video player.

  1. If you have no access to the segments that the player is currently playing back use:

  2. If you have access to the segments use:

If you are in doubt that you have access or just want to get quickly started use the first option. It will always work but can be slightly inaccurate under some circumstances.

Differences to DASH

For HLS-Live, VAST tracking is supported through , where the VAST document can be fetched by the client to request the tracking URLs. Different from DASH there are no ad-ids in the HLS-standard manifests. Therefore you need to request the vast endpoint at the right point in time to get the vast response related to the ad that is going to run.

To signal the appearance of an ad there will be a EXT-X-PROGRAMM tag in the HLS manifest: EXT-X-PROGRAM-DATE-TIME:<date-time-msec>. It is now possible to call the vastURL at the moment when an ad is playing and receive the VAST data for this ad.

The rest of the process stays the same. We will nevertheless run through every single step below.

Option 1: Player has no API to retrieve segments

The parameter needed below can be viewed at or via the https://admin.serverside.ai/api/v2/channels/:channelId API endpoint.

1. Manifest API Request

To retrieve a URL to the HLS master manifest and open a user session on the server use the following endpoint:

https://live.serverside.ai/hls/view/:channelId?&api-key=:api-key

For Example:

https://live.serverside.ai/hls/view/2aaf2594-68f5-43cc-89f5-f683963e2d23?&api-key=2aaf2594-68f5-43cc-89f5-f683963e2d23

In the response you'll get a json with mediaURL and vastURL like:

{
    "mediaURL":"https://live.serverside.ai/hls/:channelId/master.m3u8?sid=:sessionId&api-key=2aaf2594-68f5-43cc-89f5-f683963e2d23",
    "vastURL":"https://live.serverside.ai/hls/:channelId/:sessionId/vast.xml"
}

2. Starting Playback

Handover the mediaURL to the player which will load the manifests and video data.

GET Request:

https://live.serverside.ai/hls/:channelId/master.m3u8?api-key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Response Body:

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=320x180,CODECS="avc1.4d400c,mp4a.40.2",AVERAGE-BANDWIDTH="545600",BANDWIDTH=545600
1d4b9e30-3232-11ea-a76d-29ae63114b99/320x180.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=480x272,CODECS="avc1.4d4015,mp4a.40.2",AVERAGE-BANDWIDTH="765600",BANDWIDTH=765600
1d4b9e30-3232-11ea-a76d-29ae63114b99/480x270.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=640x360,CODECS="avc1.77.30,mp4a.40.2",AVERAGE-BANDWIDTH="1161600",BANDWIDTH=1161600
1d4b9e30-3232-11ea-a76d-29ae63114b99/640x360.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=960x540,CODECS="avc1.4d401f,mp4a.40.2",AVERAGE-BANDWIDTH="2140600",BANDWIDTH=2140600
1d4b9e30-3232-11ea-a76d-29ae63114b99/960x540.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2",AVERAGE-BANDWIDTH="3339600",BANDWIDTH=3339600
1d4b9e30-3232-11ea-a76d-29ae63114b99/1280x720.m3u8

3. Load-VAST data

To get the VAST document relating to the ad break that is currently playing use the vastURL from above. It will provide the original VAST response document together with the timing information for the synchronization on the player side.

The vastURL will mostly respond with a 204 (No Content). This happens because a request to the ad server is made one segment before the ad break. The VAST response from the ad server is stored and the stitching process takes place in the background. At this time the related VAST document is available to the front end as well (response with 200 OK), but as soon as the ad block is over the API will switch back to 204.

GET Request:

https://live.serverside.ai/hls/:channelId/:sessionId/320x180.m3u8/vast.xml

Response Body:

{
  "time": TIMESTAMP_IN_MS_MATCHING_IMPRESSION_TIME,
  "vast": VAST_XML_STRING
}

Example

GET Request:

https://live.serverside.ai/hls/5cc9789c-44ce-4e20-927e-2f4fc206144f/de025740-ee93-11ea-8452-1140472856cb/VAR(BANDWIDTH=0;RESOLUTION=1280;).m3u8/vast.xml

Response-Body:

time: 1599213250873
vast: "<?xml version="1.0" encoding="UTF-8"?>↵    <VAST version="3.0">↵        <Ad id="7253b601c7fd8e8c1708ca6cff1fb994-3c4ca.d1a64.4c52.30">↵            <InLine>↵                <AdSystem version="1.0">SpotXchange</AdSystem>↵                <AdTitle><![CDATA[Nowtilus Test Ad - 30sec]]></AdTitle>↵                <Description><![CDATA[]]></Description>↵                <Impression><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/Start?percentage=0]]></Impression>↵                <Error><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock?error=true]]></Error>↵                <Creatives>↵                    <Creative sequence="1">↵                        <Linear>↵                            <Duration>00:00:30</Duration>↵                            <TrackingEvents>↵                                <Tracking event="complete"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/Complete?percentage=100]]></Tracking>↵                                <Tracking event="firstQuartile"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/25?percentage=25]]></Tracking>↵                                <Tracking event="midpoint"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/50?percentage=50]]></Tracking>↵                                <Tracking event="thirdQuartile"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/75?percentage=75]]></Tracking>↵                            </TrackingEvents>↵                            <VideoClicks>↵                                <ClickTracking><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock]]></ClickTracking>↵                            </VideoClicks>↵                            <MediaFiles>↵                                <MediaFile delivery="progressive" type="video/mp4" width="480" height="360"><![CDATA[https://cdn.spotxcdn.com/media/videos/orig/1/0/10fa3ca3af9f4600e3eb580eb4da5afc.mp4]]></MediaFile>↵                            </MediaFiles>↵                        </Linear>↵                    </Creative>↵                </Creatives>↵                <Extensions>↵                    <Extension type="Pricing">↵                        <Price model="CPM" currency="USD" source="spotxchange"><![CDATA[0]]></Price>↵                    </Extension>↵                    <Extension type="SpotX-Count">↵                        <total_available><![CDATA[2]]></total_available>↵                    </Extension>↵                    <Extension type="Spotx-Regs">↵                        <GDPR>1</GDPR>↵                    </Extension>↵                    <Extension type="Spotx-User">↵                        <consent>2</consent>↵                    </Extension>↵                </Extensions>↵            </InLine>↵        </Ad>↵    </VAST>"

The VAST Manifest can now be parsed and tracking requests sent to the ad-server exactly as described in steps 4 and 5 from the above DASH example.

4. Detect the start of an ad in the stream

5. Keep track of the ad playback and send beacons

Option 2: Player has an API to retrieve segments

In the case the player has an API to retrieve the currently playing segment use the following option.

1. Manifest API Request

An outputUrl for HLS will have the following schema:

https://live.serverside.ai/hls/:channelId/master.m3u8?api-key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

2. Fetching the Master Manifest

An HLS-Live session is created by fetching the master manifest.

GET Request:

https://live.serverside.ai/hls/:channelId/master.m3u8?api-key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Response Body:

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=320x180,CODECS="avc1.4d400c,mp4a.40.2",AVERAGE-BANDWIDTH="545600",BANDWIDTH=545600
1d4b9e30-3232-11ea-a76d-29ae63114b99/320x180.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=480x272,CODECS="avc1.4d4015,mp4a.40.2",AVERAGE-BANDWIDTH="765600",BANDWIDTH=765600
1d4b9e30-3232-11ea-a76d-29ae63114b99/480x270.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=640x360,CODECS="avc1.77.30,mp4a.40.2",AVERAGE-BANDWIDTH="1161600",BANDWIDTH=1161600
1d4b9e30-3232-11ea-a76d-29ae63114b99/640x360.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=960x540,CODECS="avc1.4d401f,mp4a.40.2",AVERAGE-BANDWIDTH="2140600",BANDWIDTH=2140600
1d4b9e30-3232-11ea-a76d-29ae63114b99/960x540.m3u8
#EXT-X-STREAM-INF:FRAME-RATE="25.000",RESOLUTION=1280x720,CODECS="avc1.4d401f,mp4a.40.2",AVERAGE-BANDWIDTH="3339600",BANDWIDTH=3339600
1d4b9e30-3232-11ea-a76d-29ae63114b99/1280x720.m3u8

3. Load-VAST data

The URIs pointing to the media manifests will contain the session id. Appending /vast to any of the media manifest URI will provide the original VAST response document together with the timing information for the synchronization on the player side.

GET Request:

https://live.serverside.ai/hls/:channelId/:sessionId/320x180.m3u8/vast.xml

Response Body:

{
  "time": TIMESTAMP_IN_MS_MATCHING_IMPRESSION_TIME,
  "vast": VAST_XML_STRING
}

Example

GET Request:

https://live.serverside.ai/hls/5cc9789c-44ce-4e20-927e-2f4fc206144f/de025740-ee93-11ea-8452-1140472856cb/VAR(BANDWIDTH=0;RESOLUTION=1280;).m3u8/vast.xml

Response-Body:

time: 1599213250873
vast: "<?xml version="1.0" encoding="UTF-8"?>↵    <VAST version="3.0">↵        <Ad id="7253b601c7fd8e8c1708ca6cff1fb994-3c4ca.d1a64.4c52.30">↵            <InLine>↵                <AdSystem version="1.0">SpotXchange</AdSystem>↵                <AdTitle><![CDATA[Nowtilus Test Ad - 30sec]]></AdTitle>↵                <Description><![CDATA[]]></Description>↵                <Impression><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/Start?percentage=0]]></Impression>↵                <Error><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock?error=true]]></Error>↵                <Creatives>↵                    <Creative sequence="1">↵                        <Linear>↵                            <Duration>00:00:30</Duration>↵                            <TrackingEvents>↵                                <Tracking event="complete"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/Complete?percentage=100]]></Tracking>↵                                <Tracking event="firstQuartile"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/25?percentage=25]]></Tracking>↵                                <Tracking event="midpoint"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/50?percentage=50]]></Tracking>↵                                <Tracking event="thirdQuartile"><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock/75?percentage=75]]></Tracking>↵                            </TrackingEvents>↵                            <VideoClicks>↵                                <ClickTracking><![CDATA[http://ad-server-mock.azurewebsites.net/api/ad-server-mock]]></ClickTracking>↵                            </VideoClicks>↵                            <MediaFiles>↵                                <MediaFile delivery="progressive" type="video/mp4" width="480" height="360"><![CDATA[https://cdn.spotxcdn.com/media/videos/orig/1/0/10fa3ca3af9f4600e3eb580eb4da5afc.mp4]]></MediaFile>↵                            </MediaFiles>↵                        </Linear>↵                    </Creative>↵                </Creatives>↵                <Extensions>↵                    <Extension type="Pricing">↵                        <Price model="CPM" currency="USD" source="spotxchange"><![CDATA[0]]></Price>↵                    </Extension>↵                    <Extension type="SpotX-Count">↵                        <total_available><![CDATA[2]]></total_available>↵                    </Extension>↵                    <Extension type="Spotx-Regs">↵                        <GDPR>1</GDPR>↵                    </Extension>↵                    <Extension type="Spotx-User">↵                        <consent>2</consent>↵                    </Extension>↵                </Extensions>↵            </InLine>↵        </Ad>↵    </VAST>"

The VAST Manifest can now be parsed and tracking requests sent to the ad server exactly as described in steps 4 and 5 from the above DASH example.

Find a complete implementation of HLS tracking for JavaScript and hls.js below.

4. Detect the start of an ad in the stream

5. Keep track of the ad playback and send beacons

Example integration of Option 2

The URL to the ad-insertion enabled channel is called outputUrl and can be viewed at or via the https://admin.serverside.ai/api/v2/channels/:channelId API endpoint.

The following HTML page shows a fully working example of the HLS-live client-side tracking.

Live - DASH
Serverside.ai
Serverside.ai
Serverside.ai
Serverside.ai
Same as for DASH-Live
Same as for DASH-Live
Same as for DASH-Live
Same as for DASH-Live
2KB
hls-live_v2.zip
archive
VAST Tracking - HLS-Live Example Implementation