Table of Contents

VAST.HLS Library

The VAST.HLS library provides HTTP Live Streaming (HLS) functionality for VASTreaming applications. It supports both traditional HLS and Low-Latency HLS (LL-HLS) for live and on-demand streaming, with adaptive bitrate support, encryption, and flexible segment formats.

Overview

Feature Description
HLS Server Serve HLS streams to clients with playlist and segment delivery
LL-HLS Low-Latency HLS with partial segments for sub-second latency
HLS Client Download and parse HLS streams for playback
Adaptive Bitrate Multiple quality levels with automatic switching
Encryption AES-128 segment encryption
Segment Formats MPEG-TS and fragmented MP4 (fMP4) segments

Requirements

HLS Server Architecture

Note

HlsServer is not available as a standalone server. It operates as part of the VAST.Network.StreamingServer infrastructure and is instantiated by the StreamingServer automatically when enabled.

The diagrams below illustrate the media data flow inside the StreamingServer for the HLS server.

Live Streams

┌─────────────────────────────────────────────────────────────┐
│                 VAST.Network.StreamingServer                │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │               VAST.Network.PublishingPoint              │ │
│ │                   /hls/stream1 (Live)                   │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │                  Live Media Source                  │ │ │
│ │ │           (Camera, File, Network Stream)            │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │                            ↓                            │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │            HlsServerSink (internal class)           │ │ │
│ │ │    (Receives media, creates segments, playlists)    │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│                             ↓                               │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │               HlsServer (internal class)                │ │
│ │              (client context management)                │ │
│ └─────────────────────────────────────────────────────────┘ │
│                             ↓                               │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │                       HttpServer                        │ │
│ │            (HTTP request/response management,           │ │
│ │    based on System.Net.HttpListener or ASP.NET Core)    │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              ↓
             Multiple HTTP Clients (browsers, players)

StreamingServer manages multiple live PublishingPoint instances. Each PublishingPoint has a single source object (IMediaSource) and a single HlsServerSink (when HLS streaming is enabled). HlsServerSink prepares data (segments, playlists) for all connected clients, as the data is shared and contains no client-specific information. The data prepared by HlsServerSink is then served by HlsServer to individual clients via the HTTP server (System.Net.HttpListener or ASP.NET Core).

This architecture enables handling thousands of clients while maintaining good QoS.

VOD Streams

┌─────────────────────────────────────────────────────────────┐
│                 VAST.Network.StreamingServer                │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │               VAST.Network.PublishingPoint              │ │
│ │                    /hls/movie1 (VOD)                    │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │                   VOD Media Source                  │ │ │
│ │ │                (File, Memory Stream)                │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │                            ↓                            │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │            HlsServerSink (internal class)           │ │ │
│ │ │    (Receives media, creates segments, playlists)    │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│                             ↓                               │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │               HlsServer (internal class)                │ │
│ │              (client context management)                │ │
│ └─────────────────────────────────────────────────────────┘ │
│                             ↓                               │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │                       HttpServer                        │ │
│ │            (HTTP request/response management,           │ │
│ │    based on System.Net.HttpListener or ASP.NET Core)    │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              ↓
             Single HTTP Client (browser, player)

StreamingServer manages multiple VOD PublishingPoint instances. Each PublishingPoint has a single source object (IMediaSource) and a single HlsServerSink, and handles exactly one client because the source must maintain the current playback context (position, speed, etc.), which is unique to each connected client. HlsServerSink prepares data (segments, playlists) for that client. The data prepared by HlsServerSink is then served by HlsServer to the client via the HTTP server (System.Net.HttpListener or ASP.NET Core).

The VOD media source, typically IsoSource, uses shared metadata and indices cached in memory to skip parsing the file structure and perform only media read operations from disk.

Event Streams

┌─────────────────────────────────────────────────────────────┐
│                 VAST.Network.StreamingServer                │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │               VAST.Network.PublishingPoint              │ │
│ │                  /hls/concert1 (Event)                  │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │              Growing File Media Source              │ │ │
│ │ │                (File, Memory Stream)                │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │                            ↓                            │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │            HlsServerSink (internal class)           │ │ │
│ │ │    (Receives media, creates segments, playlists)    │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│                             ↓                               │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │               HlsServer (internal class)                │ │
│ │              (client context management)                │ │
│ └─────────────────────────────────────────────────────────┘ │
│                             ↓                               │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │                       HttpServer                        │ │
│ │            (HTTP request/response management,           │ │
│ │    based on System.Net.HttpListener or ASP.NET Core)    │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              ↓
             Single HTTP Client (browser, player)

StreamingServer manages multiple Event PublishingPoint instances. Each PublishingPoint has a single source object (IMediaSource) and a single HlsServerSink, and handles exactly one client because the source must maintain the current playback context (position, speed, etc.), which is unique to each connected client. HlsServerSink prepares data (segments, playlists) for that client. The data prepared by HlsServerSink is then served by HlsServer to the client via the HTTP server (System.Net.HttpListener or ASP.NET Core).

The Event media source, typically IsoSource, relies on a monitor source that continuously updates metadata and indices from the growing file on disk and notifies IsoSource instances about changes. A single monitor source is shared among multiple publishing points (serving multiple clients), optimizing metadata and index sharing.

Enabling HLS Server

var server = new VAST.Network.StreamingServer();

// Enable HLS
server.EnableHls = true;
server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    HlsPath = "/hls",
    MinimumSegmentDuration = TimeSpan.FromSeconds(6),
    TimeshiftBufferDuration = TimeSpan.FromSeconds(30)
};

server.Start();

Server Parameters

Configure HLS behavior via HlsServerParameters:

Parameter Default Description
HlsPath / URL path for HLS requests
MinimumSegmentDuration 5 seconds Target segment duration
TimeshiftBufferDuration 30 seconds Live playlist duration (DVR window)
InactivityTimeout 10 minutes Client disconnect timeout
EnableEncryption false Enable AES-128 encryption
EnableLowLatency false Enable LL-HLS mode
MinimumPartialSegmentDuration 0.5 seconds Partial segment duration (LL-HLS)
EnableMaximumPerformance false Optimize for 1000+ concurrent users
DiskCachePath null Path to write segments to disk
EnableVodIframeStream true Generate I-frame playlist for VOD

Segment Duration

Apple recommends segment duration of at least 6 seconds for reliable playback. The timeshift buffer should be at least 3 times the segment duration (minimum 3 segments in playlist).

server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    MinimumSegmentDuration = TimeSpan.FromSeconds(6),
    TimeshiftBufferDuration = TimeSpan.FromSeconds(30) // 5 segments
};

Client Access

Clients access HLS streams via standard HTTP requests:

http://server:port/hls/stream-name/index.m3u8

The server responds with:

  • Master playlist (index.m3u8) - lists available quality variants
  • Media playlists - lists segments for each variant
  • Segments - actual media data (TS or fMP4)

Low-Latency HLS (LL-HLS)

Enable sub-second latency streaming with partial segments and blocking playlist requests.

Enabling LL-HLS

server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    EnableLowLatency = true,
    MinimumPartialSegmentDuration = TimeSpan.FromMilliseconds(500),
    MinimumSegmentDuration = TimeSpan.FromSeconds(4)
};

LL-HLS Features

Feature Description
Partial Segments Smaller segment parts for faster delivery
Blocking Playlist Server holds request until new content available
Preload Hints Inform clients about upcoming segments
Delta Updates Send only playlist changes

Segment Formats

MPEG-TS Segments

Traditional HLS uses MPEG-2 Transport Stream segments. Compatible with all HLS clients.

Fragmented MP4 Segments (fMP4)

Modern HLS supports fragmented MP4 segments for:

  • Lower overhead than TS
  • Better codec support (HEVC on Apple devices)
  • Required for LL-HLS

The server automatically selects the appropriate format based on content and client capabilities.

Encryption

Enable AES-128 encryption for content protection:

server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    EnableEncryption = true
};

The server automatically generates encryption keys and includes key URIs in playlists.

Disk Cache

Write segments to disk for CDN distribution or external HTTP server delivery:

server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    DiskCachePath = "/var/hls-cache/"
};

The server creates a subfolder for each publishing point. You are responsible for cleaning up expired segments.

VOD Features

I-Frame Stream

For VOD publishing points, the server generates an I-frame only playlist enabling:

  • Fast forward/rewind (trick play)
  • Thumbnail generation
  • Efficient seeking
server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    EnableVodIframeStream = true // default
};

Performance Tuning

High Concurrency

For servers expecting 1000+ concurrent users:

server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    EnableMaximumPerformance = true
};

User Context Strategy

Control how client sessions are tracked:

Strategy Description
KeepInPath Session ID in URL path (default)
KeepInQuery Session ID in query string
DontKeep No session tracking (unlimited license only)
server.HlsServerParameters = new VAST.HLS.HlsServerParameters
{
    UserContextStrategy = VAST.HTTP.UserContextStrategy.KeepInPath
};

HLS Client Source

The HlsClientSource downloads and parses HLS streams for playback.

Usage

var source = new VAST.HLS.HlsClientSource();
source.Uri = "https://example.com/live/stream.m3u8";

source.NewStream += (sender, e) =>
{
    Console.WriteLine($"Stream {e.StreamIndex}: {e.MediaType}");
};

source.NewSample += (sender, e) =>
{
    ProcessSample(e.Sample);
};

source.StateChanged += (sender, state) =>
{
    if (state == MediaState.Opened)
    {
        source.Start();
    }
};

source.Open();

Authentication

For servers requiring authentication:

source.Uri = "https://username:password@example.com/live/stream.m3u8";
Note

If the username or password contains special characters, they must be URL-encoded.

Features

Feature Support
Live Streams Yes
VOD Streams Yes
Seeking Yes (VOD)
Adaptive Switching Automatic based on bandwidth
Encryption AES-128 decryption
Subtitles WebVTT support

Playback Control

// Seek (VOD only)
source.Position = TimeSpan.FromMinutes(5);

// Pause/Resume
source.Pause();
source.Start();

// Check duration
Console.WriteLine($"Duration: {source.Duration}");

Stream Selection

HlsClientSource implements IDiscardable for stream selection and discarding:

// Get total number of streams
int streamCount = source.OriginalStreamCount;

// Get media type for a specific stream
var mediaType = source.GetOriginalMediaType(0);
Console.WriteLine($"Stream 0: {mediaType.ContentType}, {mediaType.Width}x{mediaType.Height}");

// Discard specific streams (true = discard, false = include)
source.Discard(new Dictionary<int, bool>
{
    { 1, true },  // Discard stream 1
    { 2, false }  // Include stream 2
});

// Check current discard state
var discardState = source.DiscardState;
for (int i = 0; i < discardState.Count; i++)
{
    Console.WriteLine($"Stream {i}: {(discardState[i] ? "discarded" : "active")}");
}

Adaptive Bitrate Switching

Control automatic quality switching based on network conditions:

// Check if adaptive switching is supported
if (source.IsAdaptiveStreamSwitchSupported)
{
    // Enable automatic adaptive switching (default)
    source.AllowAdaptiveStreamSwitch = true;

    // Or disable for manual control
    source.AllowAdaptiveStreamSwitch = false;
}

Troubleshooting

Common Issues

Issue Cause Solution
Playback stutters Segment too short Increase MinimumSegmentDuration to 6+ seconds
High latency Standard HLS mode Enable LL-HLS for low latency
Client disconnects Inactivity timeout Increase InactivityTimeout
Memory usage high Large timeshift buffer Reduce TimeshiftBufferDuration
CDN caching issues Dynamic playlists Use DiskCachePath for static files

Debugging

Enable debug logging to diagnose issues:

VAST.Common.Log.Level = VAST.Common.Log.LogLevel.Debug;

See Also