# Live - HLS

As in the [Live - DASH ](https://nowtilus.gitbook.io/serverside-ai/video-player-app/vast-tracking/live-dash)example the HLS example follows five steps to completely implement VAST tracking client side.

{% hint style="danger" %}
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:&#x20;
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.
{% endhint %}

### Differences to DASH <a href="#differences-to-dash" id="differences-to-dash"></a>

For HLS-Live, VAST tracking is supported through [Serverside.ai](http://serverside.ai/), 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

{% hint style="info" %}
The parameter needed below can be viewed at [Serverside.ai](http://serverside.ai/) or via the `https://admin.serverside.ai/api/v2/channels/:channelId` API endpoint.
{% endhint %}

### 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.

{% hint style="warning" %}
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.
{% endhint %}

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>"
```

{% hint style="warning" %}
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.
{% endhint %}

### 4. Detect the start of an ad in the stream

[Same as for DASH-Live](https://nowtilus.gitbook.io/serverside-ai/video-player-app/live-dash#4-detect-the-start-of-an-ad-in-the-stream)

### 5. Keep track of the ad playback and send beacons

[Same as for DASH-Live](https://nowtilus.gitbook.io/serverside-ai/video-player-app/live-dash#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

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

An `outputUrl` for HLS will have the following schema:&#x20;

```
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>"
```

{% hint style="warning" %}
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.
{% endhint %}

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

### 4. Detect the start of an ad in the stream

[Same as for DASH-Live](https://nowtilus.gitbook.io/serverside-ai/video-player-app/live-dash#4-detect-the-start-of-an-ad-in-the-stream)

### 5. Keep track of the ad playback and send beacons

[Same as for DASH-Live](https://nowtilus.gitbook.io/serverside-ai/video-player-app/live-dash#5-keep-track-of-the-ad-playback-and-send-beacons)

### Example integration of Option 2

The following HTML page shows a fully working example of the [Serverside.ai](http://serverside.ai/) HLS-live client-side tracking.

{% file src="<https://1769447611-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LhEcKlJUtaMjURQZQId%2Fuploads%2Fw3RZwEGMJKRRFdy1jdHE%2Fhls-live_v2.zip?alt=media&token=7893aeaf-508b-4cce-81f5-550307214705>" %}
VAST Tracking - HLS-Live Example Implementation
{% endfile %}
