Send Sample 1
The SendSample1 demonstrates how to use IMediaSink directly to send pre-encoded audio data to a remote server. This is useful when you have pre-encoded media (from a file, capture device, or external encoder) and need to push it to a remote endpoint over RTP/RTSP.
Overview
The SendSample1 class performs the following:
- Creates an RtspPublisherSink targeting a remote RTP endpoint
- Configures a G.711 µ-law audio stream and registers it with the sink
- Opens the sink asynchronously and starts pushing on the
Openedstate - Paces audio frames against real-time on a background task, looping the source data continuously
Creating the Sink
this.sink = new VAST.RTSP.RtspPublisherSink();
this.sink.Uri = "rtp://127.0.0.1:10000";
this.sink.Error += sink_Error;
this.sink.StateChanged += sink_StateChanged;
RtspPublisherSink implements IMediaSink and pushes media data to a remote RTSP or RTP server. The URI determines the transport protocol — rtp:// sends raw RTP packets, rtsp:// uses RTSP ANNOUNCE/RECORD signaling.
Configuring the Audio Stream
audioMediaType = new VAST.Common.MediaType
{
ContentType = Common.ContentType.Audio,
CodecId = Common.Codec.G711U,
SampleRate = 8000,
Channels = 1,
Bitrate = 64000,
FrameSize = 1280
};
this.sink.AddStream(0, audioMediaType);
this.sink.Open();
The audio stream is configured as G.711 µ-law (a standard telephony codec) with the following parameters:
| Property | Value | Description |
|---|---|---|
CodecId |
G711U |
G.711 µ-law codec |
SampleRate |
8000 | 8 kHz sample rate |
Channels |
1 | Mono audio |
Bitrate |
64000 | 64 kbps |
FrameSize |
1280 | Bytes per audio frame |
AddStream registers the media stream with the sink before opening. The sink opens asynchronously — media pushing begins after the Opened state is reached.
Sink State Management
private void sink_StateChanged(object sender, Media.MediaState e)
{
lock (this)
{
switch (e)
{
case VAST.Media.MediaState.Opened:
this.sink.Start();
this.pushingTask = Task.Run(() => pushingRoutine());
break;
case VAST.Media.MediaState.Started:
// sink has been started
break;
case VAST.Media.MediaState.Closed:
// sink has been disconnected
break;
}
}
}
When the sink reaches the Opened state, Start() is called and the pushing routine is launched on a background task.
Pushing Audio Data
private void pushingRoutine()
{
DateTime streamingStarted = DateTime.Now;
long audioFrameCount = 0;
int audioBitstreamPosition = 0;
while (this.running)
{
long playbackTime = (long)(DateTime.Now - streamingStarted).Ticks;
long audioFileTime = audioFrameCount * 10000000L * 1024 / audioMediaType.SampleRate;
do
{
if (audioBitstreamPosition >= audioBuffer.Length)
{
audioBitstreamPosition = 0; // loop
}
if (audioFileTime <= playbackTime)
{
VAST.Common.VersatileBuffer packet =
VAST.Media.MediaGlobal.LockBuffer(audioMediaType.FrameSize);
packet.Append(audioBuffer, audioBitstreamPosition, audioMediaType.FrameSize);
packet.Pts = packet.Dts = audioFileTime;
packet.KeyFrame = packet.CleanPoint = true;
packet.StreamIndex = 0;
this.sink.PushMedia(0, packet);
packet.Release();
audioBitstreamPosition += audioMediaType.FrameSize;
audioFrameCount++;
audioFileTime = audioFrameCount * 10000000L
* audioMediaType.FrameSize * 8 / audioMediaType.Bitrate;
}
}
while (audioFileTime <= playbackTime);
Task.Delay(10).Wait();
}
}
The pushing routine maintains real-time pacing by comparing elapsed wall-clock time against the audio timeline:
- Buffer allocation —
MediaGlobal.LockBufferallocates a VersatileBuffer from the buffer pool.Appendcopies one frame of pre-encoded audio data into the buffer. - Timestamps —
PtsandDtsare set in 100-nanosecond units (the .NETTickstime base). All audio frames are key frames. - Pushing —
PushMediasends the buffer to the remote endpoint.Releasereturns the buffer to the pool. - Looping — when the bitstream position reaches the end of the source data, it resets to zero for continuous playback.
- Pacing — the inner
do/whileloop catches up if the thread falls behind, then the outer loop sleeps for 10 ms before checking again.
See Also
- Sample Applications — overview of all demo projects
- .NET Server Demo — parent page with setup instructions, license key configuration, and access URL reference
- VAST.RTSP Library — RTSP/RTP API reference