VAST.RTMP Library
The VAST.RTMP library provides comprehensive RTMP (Real-Time Messaging Protocol) support for VASTreaming applications. It enables receiving streams from RTMP servers, publishing streams to RTMP servers, running an RTMP server to accept incoming connections, and writing FLV files.
Overview
| Feature | Description |
|---|---|
| RTMP Client | Pull streams from RTMP servers |
| RTMP Publisher | Push streams to RTMP servers (YouTube, Twitch, etc.) |
| RTMP Server | Accept incoming publisher and client connections |
| RTMPS | Secure RTMP over TLS |
| RTMPT | RTMP tunneled over HTTP(S) |
| FLV Writer | Write media to FLV files with rotation support |
Requirements
- .NET: .NET 6.0 or later
- Dependencies: VAST.Common
Supported Codecs
Video Codecs
| Codec | Description |
|---|---|
| H.264/AVC | Advanced Video Coding |
Audio Codecs
| Codec | Description |
|---|---|
| AAC | Advanced Audio Coding |
| MP3 | MPEG Audio Layer III |
| G.711 A-law | Telephony codec |
| G.711 ยต-law | Telephony codec |
| G.726 (ADPCM) | Adaptive Differential Pulse Code Modulation |
URI Format
rtmp://[<username>:<password>@]<host>[:<port>]/<application>/<stream-name>[?<stream-parameters>]
rtmps://[<username>:<password>@]<host>[:<port>]/<application>/<stream-name>[?<stream-parameters>]
| Component | Description |
|---|---|
username:password |
Optional authentication credentials |
host |
Server hostname or IP address |
port |
Server port (default: 1935 for RTMP, 443 for RTMPS) |
application |
RTMP application name (e.g., live) |
stream-name |
Stream key or name |
stream-parameters |
Optional list of stream parameters |
If the username or password contains special characters, they must be URL-encoded.
Extended URI Format
Since the RTMP standard does not explicitly divide definitions of application and stream ID in the URI, collisions may occur when working with some third-party servers. Some third-party servers also require parameters for both application and stream ID independently.
To solve this problem, the VASTreaming library supports an extended RTMP URI format:
rtmp://[<username>:<password>@]<host>[:<port>]/<application>[?<server-parameters>]|<stream-name>[?<stream-parameters>]
With this format, <server-parameters> and <stream-parameters> can be set independently. The server URI and stream ID are divided by the | (vertical bar) character.
RTMPT Extended URI Format
For RTMPT (RTMP over HTTP) servers, the following extended format can be used:
rtmpt://[<username>:<password>@]<host>[:<port>][/<http-path>]|<application>[?<server-parameters>]|<stream-name>[?<stream-parameters>]
rtmpts://[<username>:<password>@]<host>[:<port>][/<http-path>]|<application>[?<server-parameters>]|<stream-name>[?<stream-parameters>]
A second | separator is added to differentiate the HTTP server path (which could be empty or something like /rtmpt) from the application name.
Warning
The extended URI formats with the | separator are specific to the VASTreaming library and are not part of the RTMP standard.
URI Examples
Standard RTMP:
rtmp://server.example.com/live/stream-key
RTMP with authentication:
rtmp://user:password@server.example.com/live/stream-key
RTMPS (secure):
rtmps://server.example.com:443/live/stream-key
RTMP with stream parameters:
rtmp://server.example.com/live/stream-key?token=abc123
Extended format with separate server and stream parameters:
rtmp://server.example.com/live?app_param=value|stream-key?stream_param=value
RTMPT (RTMP over HTTP):
rtmpt://server.example.com:80/rtmpt|live|stream-key
RTMPT with parameters:
rtmpt://server.example.com:80/rtmpt|live?app_param=value|stream-key?stream_param=value
RTMPT with empty HTTP path:
rtmpt://server.example.com:80|live|stream-key
RTMPTS (secure):
rtmpts://server.example.com/live/stream-key
RTMP Client
The RtmpClientSource class pulls media streams from RTMP servers.
Usage
var source = new VAST.RTMP.RtmpClientSource();
source.Uri = "rtmp://server.example.com/live/stream-key";
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();
URI Parameters
| Parameter | Default | Description |
|---|---|---|
vast-verify-handshake |
1 | Verify RTMP handshake data validity (0 or 1) |
vast-adobe-compatible |
0 | Use Adobe server-compatible RTMP handshake (0 or 1) |
vast-allow-session-timeout |
0 | Allow session to timeout on inactivity (0 or 1) |
vast-drop-on-media-type-change |
1 | Drop session if media type changes mid-stream (0 or 1) |
Example:
source.Uri = "rtmp://server.example.com/live/stream?vast-adobe-compatible=1&vast-allow-session-timeout=0";
RTMP Publisher
The RtmpPublisherSink class pushes media streams to RTMP servers such as YouTube Live, Twitch, Facebook Live, or custom RTMP ingest servers.
Usage
var sink = new VAST.RTMP.RtmpPublisherSink();
sink.Uri = "rtmp://ingest.example.com/live/stream-key";
sink.AddStream(0, videoMediaType);
sink.AddStream(1, audioMediaType);
sink.StateChanged += (sender, state) =>
{
if (state == MediaState.Opened)
{
sink.Start();
}
};
sink.Open();
// Push media samples
sink.PushMedia(0, videoSample);
sink.PushMedia(1, audioSample);
// When done
sink.Stop();
URI Parameters
| Parameter | Default | Description |
|---|---|---|
vast-auto-reconnection |
1 | Automatically reconnect on connection failure (0 or 1) |
vast-enable-send-control |
0 | Enable send buffer flow control to detect low bandwidth (0 or 1) |
vast-send-buffer-duration |
0 | Send buffer duration in 100 ns units to smoothen delivery if source has big jitter |
vast-verify-handshake |
1 | Verify RTMP handshake data validity (0 or 1) |
vast-adobe-compatible |
0 | Use Adobe server-compatible RTMP handshake (0 or 1) |
vast-allow-session-timeout |
0 | Allow session to timeout on inactivity (0 or 1) |
Example:
sink.Uri = "rtmp://server/live/stream?vast-auto-reconnection=1&vast-send-buffer-duration=30000000";
Publishing to Popular Services
YouTube Live
sink.Uri = "rtmp://a.rtmp.youtube.com/live2/your-stream-key";
Twitch
sink.Uri = "rtmp://sea02.contribute.live-video.net/app/your-stream-key";
Facebook Live
sink.Uri = "rtmps://live-api-s.facebook.com:443/rtmp/your-stream-key";
Network Statistics
All RTMP sources and sinks implement INetworkStat for monitoring connection health and transfer metrics. Statistics are updated once per second, so polling more frequently will return the same data.
var stat = source.CurrentStat;
if (stat != null)
{
Console.WriteLine($"Source stat: {stat}");
}
var stat = sink.CurrentStat;
if (stat != null)
{
Console.WriteLine($"Sink stat: {stat}");
}
RTMP Server
The RtmpServer class accepts incoming RTMP connections from both publishers (sending streams) and clients (receiving streams).
The RTMP server can operate in two modes:
| Mode | Description |
|---|---|
| Standalone | Independent server with its own transport |
| Integrated | Part of StreamingServer sharing transport with other protocols |
For standalone server usage with detailed configuration examples, see RTMP Server Demo.
Integration with StreamingServer
When used as part of StreamingServer, the RTMP server shares the network transport with other streaming protocols:
var server = new VAST.Network.StreamingServer();
// Enable RTMP
server.EnableRtmp = true;
server.RtmpServerParameters = new VAST.RTMP.RtmpServerParameters
{
RtmpApplication = "live"
};
server.RtmpServerParameters.RtmpEndPoints.Add(new IPEndPoint(IPAddress.Any, 1935));
server.Start();
Server Parameters
Configure server behavior using RtmpServerParameters:
| Parameter | Default | Description |
|---|---|---|
| RtmpEndPoints | Empty | RTMP listening endpoints (port 1935) |
| RtmpsEndPoints | Empty | RTMPS (secure) listening endpoints |
| RtmptPath | null | HTTP path for RTMPT tunneling |
| CertificateThumbprint | null | TLS certificate for RTMPS |
| RtmpApplication | "live" | Accepted application name (* for any) |
| VerifyHandshake | true | Validate RTMP handshake |
| DropRejectedPublisherImmediately | false | Drop unauthorized publishers without error response |
| DropSessionOnMediaTypeChange | true | Drop session if media type changes mid-stream |
RTMPS (Secure RTMP)
Enable secure RTMP by configuring RTMPS endpoints with a certificate:
var parameters = new VAST.RTMP.RtmpServerParameters();
parameters.RtmpsEndPoints.Add(new IPEndPoint(IPAddress.Any, 443));
parameters.CertificateThumbprint = "your-certificate-thumbprint";
RTMPT (RTMP over HTTP)
Enable RTMP tunneling over HTTP for firewall traversal:
var parameters = new VAST.RTMP.RtmpServerParameters
{
RtmptPath = "/rtmpt"
};
Clients connect via http://server:port/rtmpt or https://server:port/rtmpt (if TLS is enabled).
FLV File Writer
The FlvSink class writes media streams to FLV (Flash Video) files with optional file rotation.
Basic Usage
var sink = new VAST.RTMP.FlvSink();
sink.Uri = "recording.flv";
sink.AddStream(0, videoMediaType);
sink.AddStream(1, audioMediaType);
sink.Open();
sink.Start();
// Write samples
sink.PushMedia(0, videoSample);
sink.PushMedia(1, audioSample);
// When done
sink.Stop();
File Rotation
Automatically split recordings into multiple files:
var sink = new VAST.RTMP.FlvSink();
sink.RotationPeriod = 3600; // Rotate every hour (seconds)
int fileNumber = 0;
sink.NextUri = () => $"recording_{fileNumber++:D4}.flv";
sink.UriRotated += (sender, e) =>
{
Console.WriteLine($"Completed: {e.Uri}");
Console.WriteLine($"Duration: {e.Finished - e.Started}");
};
sink.AddStream(0, videoMediaType);
sink.AddStream(1, audioMediaType);
sink.Open();
sink.Start();
Writing to Stream
Write FLV data to a custom stream:
var memoryStream = new MemoryStream();
var sink = new VAST.RTMP.FlvSink();
sink.Stream = memoryStream;
sink.AddStream(0, videoMediaType);
sink.Open();
sink.Start();
// Write samples...
sink.Stop();
// Access the FLV data
byte[] flvData = memoryStream.ToArray();
Delayed Start
Use delayed start when the first media sample may arrive after a significant delay:
sink.Start(delayedStart: true);
// File will be created/recreated when first sample arrives
// Empty file is automatically deleted if no samples received
Global Configuration
Configure library-wide settings using RtmpGlobal:
| Setting | Default | Description |
|---|---|---|
RtmpApplication |
"live" | Default application name |
ReconnectionRetries |
int.MaxValue | Max reconnection attempts before giving up |
TransportBufferSize |
8192 | Socket buffer size |
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Connection refused | Wrong port or firewall | Check port 1935 is accessible |
| Authentication failed | Wrong credentials | Verify username/password |
| Stream rejected | Wrong application or stream name | Check URI format section |
| Bandwidth error | Upload speed too low | Reduce bitrate or resolution |
| RTMPS fails | Certificate issue | Verify certificate thumbprint |
See Also
- Supported Platforms - Platform compatibility matrix
- VAST.Common Library - Core media types and interfaces
- VAST.Network Library - Network streaming infrastructure
- RTMP Server Demo - Standalone RTMP server example