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
- .NET: .NET 6.0 or later
- Dependencies: VAST.Common, VAST.File, VAST.File.ISO, VAST.TS, VAST.RTMP, VAST.RTSP, VAST.HLS, VAST.DASH, VAST.SRT, VAST.Web, VAST.WebRTC, VAST.Image, VAST.Audio
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
- Supported Platforms - Platform compatibility matrix
- VAST.Common Library - Core media types and interfaces
- VAST.Audio - WebSocket PCM audio streaming
- VAST.DASH - MPEG-DASH streaming
- VAST.HLS - HLS streaming
- VAST.Image - MJPEG over HTTP streaming
- VAST.File - Playlist source
- VAST.File.ISO - MP4 reader/writer
- VAST.RTMP - RTMP streaming
- VAST.RTSP - RTSP/RTP streaming
- VAST.SRT - SRT streaming
- VAST.TS - TS over HTTP streaming
- VAST.Web - WebTransport streaming
- VAST.WebRTC - WebRTC streaming