Table of Contents

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

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

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