Table of Contents

VAST.Network Library

The VAST.Network library provides the StreamingServer class, the central component for multi-protocol media streaming. It manages publishing points, client connections, authorization, buffering, and integrates protocol-specific servers (RTSP, SRT, HLS, WebRTC, WebTransport, and others) into a unified streaming infrastructure.

Overview

Feature Description
Multi-Protocol Serve the same media over RTSP, SRT, HLS, MPEG-DASH, WebRTC, WebTransport, MJPEG, and more simultaneously
Publishing Points Manage named media streams with source-to-client routing
Authorization Per-connection authorization for publishers and clients
Buffering Memory, disk, and GOP-based buffering
VOD Support File-based streaming with seeking, pause, and playback rate control
Recording Record publishing point streams to rotating files
REST API Remote control of publishing points and server configuration
Statistics CPU, memory, and GPU usage monitoring

Requirements

Supported Protocols

Protocol Enable Property Parameters Property Description
RTMP EnableRtmp RtmpServerParameters Real-Time Messaging Protocol
RTSP EnableRtsp RtspServerParameters Real Time Streaming Protocol
SRT EnableSrt SrtServerParameters Secure Reliable Transport
WebTransport EnableWebTransport WebTransportServerParameters WebTransport over HTTP/3
HLS EnableHls HlsServerParameters HTTP Live Streaming
MPEG-DASH EnableMpegDash DashServerParameters Dynamic Adaptive Streaming over HTTP
WebRTC EnableWebRtc WebRtcServerParameters Web Real-Time Communication
MJPEG over HTTP EnableMjpeg MjpegServerParameters Motion JPEG over HTTP
TS over HTTP EnableTsHttp TsHttpServerParameters MPEG-2 Transport Stream over HTTP
WebSocket PCM EnableWsPcm WsPcmServerParameters WebSocket PCM audio streaming
Note

All HTTP-based protocols (HLS, MPEG-DASH, WebRTC, WebTransport, MJPEG over HTTP, TS over HTTP, WebSocket PCM) require EnableHttp = true and share the same HTTP server endpoints.

StreamingServer

The StreamingServer class is the main entry point for multi-protocol media streaming.

Basic Usage

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

// Configure HTTP server (required for HTTP-based protocols)
server.EnableHttp = true;
server.HttpServerParameters = new VAST.HTTP.HttpServerParameters
{
    HttpPorts = new List<int> { 8080 },
    HttpsPorts = new List<int> { 8443 },
};

// Enable protocols
server.EnableRtsp = true;
server.EnableSrt = true;
server.EnableHls = true;

// Start the server
server.Start();

// Create a publishing point with a pull source
server.CreatePublishingPoint("/stream1", "rtsp://camera.example.com/stream");

Server Configuration

Property Default Description
EnableHttp false Enable the HTTP server (required for HTTP-based protocols)
HttpServerParameters HTTP server port configuration
CertificateThumbprint null SSL/TLS certificate thumbprint for secure protocols
EnableJsonApi false Enable the REST API endpoint
ApiServerParameters REST API server parameters
EnableRtmp false Enable the RTMP server
RtmpServerParameters RTMP server parameters
EnableRtsp false Enable the RTSP server
RtspServerParameters RTSP server parameters
EnableSrt false Enable the SRT server
SrtServerParameters SRT server parameters
EnableHls false Enable the HLS server
HlsServerParameters HLS server parameters
EnableMpegDash false Enable the MPEG-DASH server
DashServerParameters MPEG-DASH server parameters
EnableWebRtc false Enable the WebRTC server
WebRtcServerParameters WebRTC server parameters
EnableWebTransport false Enable the WebTransport server
WebTransportServerParameters WebTransport server parameters
EnableMjpeg false Enable the MJPEG over HTTP server
MjpegServerParameters MJPEG over HTTP server parameters
EnableTsHttp false Enable the TS over HTTP server
TsHttpServerParameters TS over HTTP server parameters
EnableWsPcm false Enable the WebSocket PCM audio server
WsPcmServerParameters WebSocket PCM audio server parameters
EnableTcpServer false Enable the raw TCP server
TcpServerParameters TCP server parameters
FileTransferRequestedHandler null Delegate that handles file transfer requests
CacheFolder null Cache folder for VOD and buffering
EnableFileCache true Enable file metadata cache for VOD sources
EnableStat true Enable performance statistics collection
Stat Server performance statistics (read-only)

Lifecycle

// Start with default HTTP server
server.Start();

// Or start with a custom HttpServer instance
server.Start(existingHttpServer);

// Update settings at runtime (restarts affected protocol servers)
server.EnableHls = true;
server.Update();

// Stop and release all resources
server.Stop();

Events

Event Description
PublishingPointRequested A client or publisher requested a publishing point that does not exist; create it on demand
PublishingPointDisposing A publishing point is about to be disposed
Authorize A new publisher or client connection requires authorization
PublisherConnected A publisher has connected and its publishing point is ready
ClientConnected A client has connected to a publishing point
Disconnected A publisher or client has disconnected
Error An error occurred on a connection

Publishing Points

A PublishingPoint represents a named media stream served to clients. Each publishing point has a single media source and can have multiple clients connected simultaneously.

Creating Publishing Points

Create a publishing point with a pull source URI:

Guid id = server.CreatePublishingPoint("/stream1", "rtsp://camera.example.com/stream");

Create a publishing point with a custom media source:

Guid id = server.CreatePublishingPoint("/stream1", myMediaSource);

Create a VOD publishing point:

Guid id = server.CreatePublishingPoint("/movie1", "file:///path/to/movie.mp4", StreamingMode.Vod);

On-Demand Publishing Points

Use the PublishingPointRequested event to create publishing points dynamically when requested:

server.PublishingPointRequested += (connectionId, connectionInfo, createdParameters) =>
{
    string path = connectionInfo.PublishingPath;
    server.CreatePublishingPoint(path, ResolveSourceUri(path));
    createdParameters.ActualPublishingPath = path;
};

Publishing Point Parameters

Configure publishing point behavior using PublishingPointParameters:

Parameter Default Description
Title null Human-readable description
AllowedProtocols All Streaming protocols allowed for this publishing point
BufferingType None Buffering type: None, Memory, Disk, or Gop
BufferDuration null Buffer duration
Loop false Loop the source endlessly
StartSuspended false Start in suspended state; call Resume() to begin
IsTemporary false Temporary VOD publishing point; automatically disposed when last client disconnects
OpeningTimeout null Maximum time to wait for media data after opening
ExpirationTimeout null Auto-expire the publishing point after this duration
InactivityTimeout null Dispose the publishing point after this period of inactivity; applies only for publishing points created via API
NoClientsTimeout null Dispose the publishing point after this period with no connected clients
MaxVideoWidth 0 Maximum video width for transcoding sinks; 0 means no limit
MaxVideoHeight 0 Maximum video height for transcoding sinks; 0 means no limit
MaxVideoFramerate null Maximum video framerate for transcoding sinks; null means no limit
StreamMap null Stream index mapping dictionary
StreamMapper null Stream mapping callback for dynamic stream selection
StartPositionAlignment Before Keyframe alignment for start position: Before or After
EndPositionAlignment Before Keyframe alignment for end position: Before or After
DeleteFileOnClose false Delete the source file when the publishing point closes
UserData null User-attachable data object

Streaming Modes

Mode Description
Live Live streaming with no defined beginning or end
Vod Video on demand; file-based streaming with known duration and interactive playback
Event Has a defined beginning but may not have a defined end

Buffering Types

Type Description
None No buffering
Memory Media samples are buffered in memory
Disk Media samples are buffered on disk
Gop Last Group of Pictures (GOP) is cached in memory for quick client start

Managing Publishing Points

// List all active publishing points
List<PublishingPoint> points = server.GetPublishingPoints();

// Get a publishing point by path
PublishingPoint pp = server.GetPublishingPoint("/stream1");

// Check if a publishing point has connected clients
bool inUse = server.IsPublishingPointInUse("/stream1");

// Disconnect a publishing point
pp.Disconnect(PublishingPoint.ShutdownReason.UserInitiated);

// Resume a suspended publishing point
pp.Resume();

MixingSource

MixingSource extends MixingSource and can be used as a publishing point source that combines multiple input sources with video compositing and audio mixing. Unlike the base class, it supports using other publishing points as input sources, enabling scenarios such as combining multiple live camera streams into a single composited output. To reference a publishing point as a source, use the URI format vast://publishing-point/<publishing-path>.

MixingSource-based publishing points can be created and controlled via the REST API, allowing dynamic source management, layout changes, and transcoding configuration at runtime.

// POST /v1/publishing-point
{
  "token": "...",
  "path": "/mixed",
  "sources": [
    { "uri": "vast://publishing-point/camera1" },
    { "uri": "vast://publishing-point/camera2" },
    { "uri": "rtmp://external.example.com/live/stream" }
  ],
  ...
}

Adding Sinks

Use the AddSink method to attach a custom media sink to a publishing point. The sink receives all media streams from the publishing point source alongside protocol-based clients.

// Create a file writer sink
var fileSink = new VAST.File.ISO.IsoSink();
fileSink.Uri = "/recordings/stream1.mp4";

// Attach the sink to an existing publishing point
PublishingPoint pp = server.GetPublishingPoint("/stream1");
pp.AddSink(fileSink);

When a sink is added, the publishing point opens the sink, configures its streams according to the current source media types and stream mapping, and starts pushing media samples to it. The sink remains active until it is disposed or the publishing point is disconnected.

Recording

Start recording a publishing point to a file:

Guid recordingId = pp.StartRecording("/recordings/stream1.mp4");

Start recording with file rotation:

int rotationCounter = 0;
Guid recordingId = pp.StartRecording(
    "mp4",
    () => $"/recordings/stream1_{rotationCounter++}.mp4",
    rotationPeriod: 3600);  // Rotate every 3600 seconds

Stream Mapping

Stream mapping controls how source streams are routed to sinks. By default, source streams are mapped to sink streams 1:1 (stream 0 → 0, stream 1 → 1, etc.). Use stream mapping to reorder streams, swap streams, or discard unwanted streams.

Static Stream Mapping

Use StreamMap to define a fixed mapping at publishing point creation time. The dictionary maps input stream indices (keys) to output stream indices (values). Set the output index to -1 to discard a stream. Output indices must form a consecutive sequence starting from 0.

// Map source streams to the same output streams (default behavior)
parameters.StreamMap = new Dictionary<int, int>
{
    { 0, 0 },
    { 1, 1 },
};

// Swap video and audio streams
parameters.StreamMap = new Dictionary<int, int>
{
    { 0, 1 },
    { 1, 0 },
};

// Discard the first stream (e.g., video), keep the second (e.g., audio only)
parameters.StreamMap = new Dictionary<int, int>
{
    { 0, -1 },
    { 1, 0 },
};

Dynamic Stream Mapping

Use StreamMapper when source media types are unknown at publishing point creation time. The delegate is called when all source media types have been detected, allowing stream mapping decisions based on actual codec and media type information.

parameters.StreamMapper = (publishingPoint, sourceMediaTypes, streamMap) =>
{
    // sourceMediaTypes contains detected media types indexed by stream index
    // streamMap is pre-initialized (1:1 or from StreamMap) and can be modified in-place

    streamMap.Clear();

    int outputIndex = 0;
    for (int i = 0; i < sourceMediaTypes.Count; i++)
    {
        if (sourceMediaTypes[i].ContentType == ContentType.Video)
        {
            streamMap[i] = outputIndex++;  // keep video streams
        }
        else
        {
            streamMap[i] = -1;  // discard non-video streams
        }
    }
};

Shutdown Reasons

Reason Description
Unknown Unknown reason
SourceDown Media source disconnected
UserInitiated User-initiated shutdown
DurationLimit Reached maximum duration
OpeningTimeout Timeout waiting for media data
NoClients No connected clients (when NoClientsTimeout is set)
InactivityTimeout Inactivity timeout triggered

Authorization

The Authorize event controls which connections are accepted:

server.Authorize += (connectionId, connectionInfo) =>
{
    // connectionInfo.ConnectionType - Publisher or Client
    // connectionInfo.InboundUri - the connection URI
    // connectionInfo.PublishingPath - the publishing path
    // connectionInfo.EndPoint - the network endpoint

    // Synchronous authorization
    connectionInfo.IsValid = IsAuthorized(connectionInfo);

    // Or asynchronous authorization
    connectionInfo.IsValidAwaiter = IsAuthorizedAsync(connectionInfo);
};

ConnectionInfo Properties

Property Description
ConnectionId Unique connection identifier
ConnectionType Publisher, Client, or Undetermined
InboundUri Connection URI
PublishingPath Publishing path extracted from URI
EndPoint Network endpoint (IP address, port, protocol)
AdditionalInfo Protocol-specific data (e.g., HTTP headers)
IsValid Set to true or false for synchronous authorization
IsValidAwaiter Set to a Task<bool> for asynchronous authorization

HTTP Server

The HTTP server provides the infrastructure for all HTTP-based protocols. Configure it using HttpServerParameters:

server.HttpServerParameters = new VAST.HTTP.HttpServerParameters
{
    HttpPorts = new List<int> { 80, 8080 },
    HttpsPorts = new List<int> { 443, 8443 },
};
Parameter Default Description
HttpPorts empty List of ports to listen on for HTTP
HttpsPorts empty List of ports to listen on for HTTPS
Note

On Windows in HttpListener mode, specifying CertificateThumbprint alone is not sufficient. You must also configure URL reservations or SSL certificates using netsh:

// either create urlacl rule allowing HTTP access to the port
netsh http add urlacl url=http://*:<port>/ user=Everyone
// or associate the certificate to your application explicitly
netsh http add sslcert ipport=0.0.0.0:<https-port> certhash=<thumbprint> appid={<application-guid>}

Statistics

When EnableStat is true, the Stat property provides server performance metrics:

var stat = server.Stat;
Console.WriteLine($"Connections: {stat.ConnectionCount}");
Console.WriteLine($"Publishing points: {stat.PublishingPointCount}");
Console.WriteLine($"CPU: {stat.CpuUsage:F1}%");
Console.WriteLine($"Memory: {stat.MemoryUsage:F1}%");
Console.WriteLine($"GPU 3D: {stat.Gpu3DUsage:F1}%");
Console.WriteLine($"GPU Decoder: {stat.GpuDecoderUsage:F1}%");
Console.WriteLine($"GPU Encoder: {stat.GpuEncoderUsage:F1}%");
Property Description
ConnectionCount Number of active connections
PublishingPointCount Number of active publishing points
CpuUsage Average CPU usage percentage
MemoryUsage Average memory usage percentage
Gpu3DUsage GPU 3D engine usage percentage
GpuDecoderUsage GPU video decoder usage percentage
GpuEncoderUsage GPU video encoder usage percentage
StatLogInterval Statistics logging interval (default: 1 minute)

REST API

When EnableJsonApi is true, the server exposes a REST API for remote management. Configure it using ApiServerParameters:

server.EnableJsonApi = true;
server.ApiServerParameters = new VAST.Network.ApiServerParameters
{
    IsOnlineMode = true,
};
Parameter Default Description
IsOnlineMode true Online mode flag
Users null Authorized username-password pairs
SharedSecretKey null Shared secret for token-based authentication
SharedTokenExpiration null Token expiration duration

Authentication

The API supports two authentication mechanisms:

Session-based authentication — clients authenticate via /v1/auth with a username and password and receive a session token. Tokens expire after inactivity.

Shared key token authentication — uses SHA-512 hashing with a shared secret key configured via SharedSecretKey. Token format: sk1-{timestamp}-{hash}. Default expiration is 60 seconds, configurable via SharedTokenExpiration.

API Endpoints

All endpoints use JSON request and response bodies. Responses include a result field set to "OK" on success or an error description on failure.

GET /v1/ip

Returns the requesting client's IP address. Does not require authentication.

// Response
{
  "result": "OK",
  "ip": "192.168.1.100"
}

POST /v1/auth

Authenticates a user with username and password, returns a session token.

// Request
{
  "name": "username",
  "password": "password"
}

// Response
{
  "result": "OK",
  "token": "550e8400-e29b-41d4-a716-446655440000"
}

DELETE /v1/auth

Revokes an authorized session token.

// Request
{
  "token": "550e8400-e29b-41d4-a716-446655440000"
}

POST /v1/publishing-point

Creates a new publishing point with media sources and optional sinks.

// Request
{
  "token": "...",
  "path": "/stream1",
  "title": "My Live Stream",
  "streaming-mode": "live",
  "allowed-protocols": "hls,dash",
  "loop": false,
  "expiration-timeout": 3600,
  "inactivity-timeout": 1800,
  "sources": [
    {
      "uri": "rtmp://source.example.com/live/stream"
    }
  ],
  "sinks": [
    {
      "uri": "file:///recordings/stream1.mp4",
      "format": "mediafile"
    }
  ],
  "processing": {
    "video": {
      "transcoding": true,
      "tracks": [{ "width": 1920, "height": 1080, "bitrate": 5000000, "codec": "h264" }]
    },
    "audio": {
      "transcoding": true,
      "tracks": [{ "sample-rate": 48000, "channels": 2, "bitrate": 128000, "codec": "aac" }]
    }
  }
}

// Response
{
  "result": "OK",
  "publishing-point-id": "12345678-1234-5678-1234-567812345678"
}

GET /v1/publishing-point/{id-or-path}

Retrieves publishing point details by ID (UUID) or path.

PUT /v1/publishing-point/{id-or-path}

Updates an existing publishing point (sources, sinks, processing settings).

DELETE /v1/publishing-point/{id-or-path}

Stops and removes a publishing point.

POST /v1/sink

Adds a sink (output destination) to an existing publishing point. Either path or publishing-point-id must be specified to identify the target publishing point.

// Request
{
  "token": "...",
  "path": "/stream1",
  "sink": {
    "uri": "file:///recordings/backup.mp4",
    "format": "mediafile"
  }
}

DELETE /v1/sink/{sink-id}

Removes a sink by its client ID.

GET /v1/stat

Retrieves server statistics including connection count, resource usage, and GPU metrics.

// Response
{
  "result": "OK",
  "stat": {
    "connection-count": 42,
    "publishing-point-count": 5,
    "cpu-usage": 45.3,
    "memory-usage": 62.1,
    "gpu-3d-usage": 0.0,
    "gpu-decoder-usage": 0.0,
    "gpu-encoder-usage": 35.5
  }
}

GET /v1/test-speed

Speed testing endpoint. GET downloads random data for download speed testing. POST accepts upload for upload speed testing.

Troubleshooting

Common Issues

Issue Cause Solution
Port already in use Another process is using the port Change the HTTP/HTTPS port or stop the conflicting process
HTTPS not working Missing or invalid certificate, or missing Windows configuration Verify CertificateThumbprint points to a valid installed certificate; on Windows HttpListener mode, configure URL reservations and SSL certificate binding using netsh
Publishing point not found Path mismatch Ensure the client requests the exact path used in CreatePublishingPoint
Authorization rejected IsValid not set to true Verify the Authorize event handler sets connectionInfo.IsValid = true
Protocol server not starting HTTP server not enabled Set EnableHttp = true for HTTP-based protocols
VOD seeking not working Source doesn't support interactive features Use a file-based source (e.g., MP4) with StreamingMode.Vod

See Also