VOOZH about

URL: https://www.nuget.org/packages/SharpRTSP/

⇱ NuGet Gallery | SharpRTSP 1.11.1




SharpRTSP 1.11.1

dotnet add package SharpRTSP --version 1.11.1
 
 
NuGet\Install-Package SharpRTSP -Version 1.11.1
 
 
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SharpRTSP" Version="1.11.1" />
 
 
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SharpRTSP" Version="1.11.1" />
 
Directory.Packages.props
<PackageReference Include="SharpRTSP" />
 
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SharpRTSP --version 1.11.1
 
 
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: SharpRTSP, 1.11.1"
 
 
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SharpRTSP@1.11.1
 
 
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SharpRTSP&version=1.11.1
 
Install as a Cake Addin
#tool nuget:?package=SharpRTSP&version=1.11.1
 
Install as a Cake Tool
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Sharp RTSP

👁 Nuget

The source of the nuget package SharpRTSP is in branch donetcore

A C# library to build RTSP Clients, RTSP Servers and handle RTP data streams. The library has several examples.

  • RTSP Client Example - will connect to a RTSP server and receive Video and Audio in H264, H265/HEVC, G711, AAC and AMR formats. UDP, TCP and Multicast are supported. The data received is written to files.
  • RTSP Camera Server Example - A YUV Image Generator and a very simple H264 Encoder generate H264 NALs which are then delivered via a RTSP Server to clients with MD5 and SHA256 Digest Options
  • RTP Receiver - will receieve RTP and RTCP packets and pass them to a transport handler
  • RTSP Server - will accept RTSP connections and talk to clients
  • RTP Sender - will send RTP packets to clients
  • Transport Handler - Transport handlers for H264, H265/HEVC, G711 and AMR are provided.

:warning: : This library does not handle the decoding of the video or audio (eg converting H264 into a bitmap). SharpRTSP is limited to the transport layer and generates the raw data that you need to feed into a video decoder or audio decoder. Many people use FFMPEG or use Hardware Accelerated Operating System APIs to do the decoding.

Walkthrough of the RTSP Client Example

This is a walkthrough of an old version of the RTSP Client Example which highlights the main way to use the library.

  • STEP 1 - Open TCP Socket connection to the RTSP Server

     // Connect to a RTSP Server
     tcp_socket = new Rtsp.RtspTcpTransport(host,port);
    
     if (tcp_socket.Connected == false)
     {
     Console.WriteLine("Error - did not connect");
     return;
     }
    

    This opens a connection for a 'TCP' mode RTSP/RTP session where RTP packets are set in the RTSP socket.

  • STEP 2 - Create a RTSP Listener and attach it to the RTSP TCP Socket

     // Connect a RTSP Listener to the TCP Socket to send messages and listen for replies
     rtsp_client = new Rtsp.RtspListener(tcp_socket);
    
     rtsp_client.MessageReceived += Rtsp_client_MessageReceived;
     rtsp_client.DataReceived += Rtsp_client_DataReceived;
    
     rtsp_client.Start(); // start reading messages from the server
    

    The RTSP Listener class lets you SEND messages to the RTSP Server (see below).
    The RTSP Listner class has a worker thread that listens for replies from the RTSP Server.
    When replies are received the MessageReceived Event is fired.
    When RTP packets are received the DataReceived Event is fired.

  • STEP 3 - Send Messages to the RTSP Server

    The samples below show how to send messages.

    Send OPTIONS with this code :

     Rtsp.Messages.RtspRequest options_message = new Rtsp. Messages.RtspRequestOptions();
     options_message.RtspUri = new Uri(url);
     rtsp_client.SendMessage(options_message);
    

    Send DESCRIBE with this code :

     // send the Describe
     Rtsp.Messages.RtspRequest describe_message = new Rtsp.Messages.RtspRequestDescribe();
     describe_message.RtspUri = new Uri(url);
     rtsp_client.SendMessage(describe_message);
     // The reply will include the SDP data
    

    Send SETUP with this code :

     // the value of 'control' comes from parsing the SDP for the desired video or audio sub-stream
     Rtsp.Messages.RtspRequest setup_message = new Rtsp.Messages.RtspRequestSetup();
     setup_message.RtspUri = new Uri(url + "/" + control);
     setup_message.AddHeader("Transport: RTP/AVP/TCP;interleaved=0");
     rtsp_client.SendMessage(setup_message);
     // The reply will include the Session
    

    Send PLAY with this code :

     // the value of 'session' comes from the reply of the SETUP command
     Rtsp.Messages.RtspRequest play_message = new Rtsp.Messages.RtspRequestPlay();
     play_message.RtspUri = new Uri(url);
     play_message.Session = session;
     rtsp_client.SendMessage(play_message);
    
  • STEP 4 - Handle Replies when the MessageReceived event is fired

    This example assumes the main program sends an OPTIONS Command.
    It looks for a reply from the server for OPTIONS and then sends DESCRIBE.
    It looks for a reply from the server for DESCRIBE and then sends SETUP (for the video stream)
    It looks for a reply from the server for SETUP and then sends PLAY.
    Once PLAY has been sent the video, in the form of RTP packets, will be received.

     private void Rtsp_client_MessageReceived(object sender, Rtsp.RtspChunkEventArgs e)
     {
     Rtsp.Messages.RtspResponse message = e.Message as Rtsp.Messages.RtspResponse;
    
     Console.WriteLine("Received " + message.OriginalRequest.ToString());
    
     if (message.OriginalRequest != null && message.OriginalRequest is Rtsp.Messages.RtspRequestOptions)
     {
     // send the DESCRIBE
     Rtsp.Messages.RtspRequest describe_message = new Rtsp.Messages.RtspRequestDescribe();
     describe_message.RtspUri = new Uri(url);
     rtsp_client.SendMessage(describe_message);
     }
    
     if (message.OriginalRequest != null && message.OriginalRequest is Rtsp.Messages.RtspRequestDescribe)
     {
     // Got a reply for DESCRIBE
     // Examine the SDP
     Console.Write(System.Text.Encoding.UTF8.GetString(message.Data));
    
     Rtsp.Sdp.SdpFile sdp_data;
     using (StreamReader sdp_stream = new StreamReader(new MemoryStream(message.Data)))
     {
     sdp_data = Rtsp.Sdp.SdpFile.Read(sdp_stream);
     }
    
     // Process each 'Media' Attribute in the SDP.
     // If the attribute is for Video, then send a SETUP
     for (int x = 0; x < sdp_data.Medias.Count; x++)
     {
     if (sdp_data.Medias[x].GetMediaType() == Rtsp.Sdp.Media.MediaType.video)
     {
     // seach the atributes for control, fmtp and rtpmap
     String control = ""; // the "track" or "stream id"
     String fmtp = ""; // holds SPS and PPS
     String rtpmap = ""; // holds the Payload format, 96 is often used with H264
     foreach (Rtsp.Sdp.Attribut attrib in sdp_data.Medias[x].Attributs)
     {
     if (attrib.Key.Equals("control")) control = attrib.Value;
     if (attrib.Key.Equals("fmtp")) fmtp = attrib.Value;
     if (attrib.Key.Equals("rtpmap")) rtpmap = attrib.Value;
     }
    
     // Get the Payload format number for the Video Stream
     String[] split_rtpmap = rtpmap.Split(' ');
     video_payload = 0;
     bool result = Int32.TryParse(split_rtpmap[0], out video_payload);
    
     // Send SETUP for the Video Stream
     // using Interleaved mode (RTP frames over the RTSP socket)
     Rtsp.Messages.RtspRequest setup_message = new Rtsp.Messages.RtspRequestSetup();
     setup_message.RtspUri = new Uri(url + "/" + control);
     setup_message.AddHeader("Transport: RTP/AVP/TCP;interleaved=0");
     rtsp_client.SendMessage(setup_message);
     }
     }
     }
    
     if (message.OriginalRequest != null && message.OriginalRequest is Rtsp.Messages.RtspRequestSetup)
     {
     // Got Reply to SETUP
     Console.WriteLine("Got reply from Setup. Session is " + message.Session);
    
     String session = message.Session; // Session value used with Play, Pause, Teardown
    
     // Send PLAY
     Rtsp.Messages.RtspRequest play_message = new Rtsp.Messages.RtspRequestPlay();
     play_message.RtspUri = new Uri(url);
     play_message.Session = session;
     rtsp_client.SendMessage(play_message);
     }
    
     if (message.OriginalRequest != null && message.OriginalRequest is Rtsp.Messages.RtspRequestPlay)
     {
     // Got Reply to PLAY
     Console.WriteLine("Got reply from Play " + message.Command);
     }
     }
    
  • STEP 5 - Handle RTP Video

    This code handles each incoming RTP packet, combining RTP packets that are all part of the same frame of video (using the Marker Bit). Once a full frame is received it can be passed to a De-packetiser to get the compressed video data

     List<byte[]> temporary_rtp_payloads = new List<byte[]>();
    
     private void Rtsp_client_DataReceived(object sender, Rtsp.RtspChunkEventArgs e)
     {
     // RTP Packet Header
     // 0 - Version, P, X, CC, M, PT and Sequence Number
     //32 - Timestamp
     //64 - SSRC
     //96 - CSRCs (optional)
     //nn - Extension ID and Length
     //nn - Extension header
    
     int rtp_version = (e.Message.Data[0] >> 6);
     int rtp_padding = (e.Message.Data[0] >> 5) & 0x01;
     int rtp_extension = (e.Message.Data[0] >> 4) & 0x01;
     int rtp_csrc_count = (e.Message.Data[0] >> 0) & 0x0F;
     int rtp_marker = (e.Message.Data[1] >> 7) & 0x01;
     int rtp_payload_type = (e.Message.Data[1] >> 0) & 0x7F;
     uint rtp_sequence_number = ((uint)e.Message.Data[2] << 8) + (uint)(e.Message.Data[3]);
     uint rtp_timestamp = ((uint)e.Message.Data[4] <<24) + (uint)(e.Message.Data[5] << 16) + (uint)(e.Message.Data[6] << 8) + (uint)(e.Message.Data[7]);
     uint rtp_ssrc = ((uint)e.Message.Data[8] << 24) + (uint)(e.Message.Data[9] << 16) + (uint)(e.Message.Data[10] << 8) + (uint)(e.Message.Data[11]);
    
     int rtp_payload_start = 4 // V,P,M,SEQ
     + 4 // time stamp
     + 4 // ssrc
     + (4 * rtp_csrc_count); // zero or more csrcs
    
     uint rtp_extension_id = 0;
     uint rtp_extension_size = 0;
     if (rtp_extension == 1)
     {
     rtp_extension_id = ((uint)e.Message.Data[rtp_payload_start + 0] << 8) + (uint)(e.Message.Data[rtp_payload_start + 1] << 0);
     rtp_extension_size = ((uint)e.Message.Data[rtp_payload_start + 2] << 8) + (uint)(e.Message.Data[rtp_payload_start + 3] << 0);
     rtp_payload_start += 4 + (int)rtp_extension_size; // extension header and extension payload
     }
    
     Console.WriteLine("RTP Data"
     + " V=" + rtp_version
     + " P=" + rtp_padding
     + " X=" + rtp_extension
     + " CC=" + rtp_csrc_count
     + " M=" + rtp_marker
     + " PT=" + rtp_payload_type
     + " Seq=" + rtp_sequence_number
     + " Time=" + rtp_timestamp
     + " SSRC=" + rtp_ssrc
     + " Size=" + e.Message.Data.Length);
    
    
     if (rtp_payload_type != video_payload)
     {
     Console.WriteLine("Ignoring this RTP payload");
     return; // ignore this data
     }
    
    
     // If rtp_marker is '1' then this is the final transmission for this packet.
     // If rtp_marker is '0' we need to accumulate data with the same timestamp
    
     // ToDo - Check Timestamp matches
    
     // Add to the tempoary_rtp List
     byte[] rtp_payload = new byte[e.Message.Data.Length - rtp_payload_start]; // payload with RTP header removed
     System.Array.Copy(e.Message.Data, rtp_payload_start, rtp_payload, 0, rtp_payload.Length); // copy payload
     temporary_rtp_payloads.Add(rtp_payload);
    
     if (rtp_marker == 1)
     {
     // Process the RTP frame
     Process_RTP_Frame(temporary_rtp_payloads);
     temporary_rtp_payloads.Clear();
     }
     }
    
  • STEP 6 - Process RTP frame

    An RTP frame consists of 1 or more RTP packets
    H264 video is packed into one or more RTP packets and this sample extracts Normal Packing and Fragmented Unit type A packing (the common two)
    This example writes the video to a .264 file which can be played with FFPLAY

     FileStream fs = null;
     byte[] nal_header = new byte[]{ 0x00, 0x00, 0x00, 0x01 };
     int norm, fu_a, fu_b, stap_a, stap_b, mtap16, mtap24 = 0; // stats counters
    
     public void Process_RTP_Frame(List<byte[]>rtp_payloads)
     {
     Console.WriteLine("RTP Data comprised of " + rtp_payloads.Count + " rtp packets");
    
     if (fs == null)
     {
     // Create the file
     String filename = "rtsp_capture_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".h264";
     fs = new FileStream(filename, FileMode.Create);
    
     // TODO. Get SPS and PPS from the SDP Attributes (the fmtp attribute) and write to the file
     // for IP cameras that only out the SPS and PPS out-of-band
     }
    
     for (int payload_index = 0; payload_index < rtp_payloads.Count; payload_index++) {
     // Examine the first rtp_payload and the first byte (the NAL header)
     int nal_header_f_bit = (rtp_payloads[payload_index][0] >> 7) & 0x01;
     int nal_header_nri = (rtp_payloads[payload_index][0] >> 5) & 0x03;
     int nal_header_type = (rtp_payloads[payload_index][0] >> 0) & 0x1F;
    
     // If the NAL Header Type is in the range 1..23 this is a normal NAL (not fragmented)
     // So write the NAL to the file
     if (nal_header_type >= 1 && nal_header_type <= 23)
     {
     Console.WriteLine("Normal NAL");
     norm++;
     fs.Write(nal_header, 0, nal_header.Length);
     fs.Write(rtp_payloads[payload_index], 0, rtp_payloads[payload_index].Length);
     }
     else if (nal_header_type == 24)
     {
     // There are 4 types of Aggregation Packet (multiple NALs in one RTP packet)
     Console.WriteLine("Agg STAP-A not supported");
     stap_a++;
     }
     else if (nal_header_type == 25)
     {
     // There are 4 types of Aggregation Packet (multiple NALs in one RTP packet)
     Console.WriteLine("Agg STAP-B not supported");
     stap_b++;
     }
     else if (nal_header_type == 26)
     {
     // There are 4 types of Aggregation Packet (multiple NALs in one RTP packet)
     Console.WriteLine("Agg MTAP16 not supported");
     mtap16++;
     }
     else if (nal_header_type == 27)
     {
     // There are 4 types of Aggregation Packet (multiple NALs in one RTP packet)
     Console.WriteLine("Agg MTAP24 not supported");
     mtap24++;
     }
     else if (nal_header_type == 28)
     {
     Console.WriteLine("Fragmented Packet Type FU-A");
     fu_a++;
    
     // Parse Fragmentation Unit Header
     int fu_header_s = (rtp_payloads[payload_index][1] >> 7) & 0x01; // start marker
     int fu_header_e = (rtp_payloads[payload_index][1] >> 6) & 0x01; // end marker
     int fu_header_r = (rtp_payloads[payload_index][1] >> 5) & 0x01; // reserved. should be 0
     int fu_header_type = (rtp_payloads[payload_index][1] >> 0) & 0x1F; // Original NAL unit header
    
     Console.WriteLine("Frag FU-A s="+fu_header_s + "e="+fu_header_e);
    
     // Start Flag set
     if (fu_header_s == 1)
     {
     // Write 00 00 00 01 header
     fs.Write(nal_header, 0, nal_header.Length); // 0x00 0x00 0x00 0x01
    
     // Modify the NAL Header that was at the start of the RTP packet
     // Keep the F and NRI flags but substitute the type field with the fu_header_type
     byte reconstructed_nal_type = (byte)((nal_header_nri << 5) + fu_header_type);
     fs.WriteByte(reconstructed_nal_type); // NAL Unit Type
     fs.Write(rtp_payloads[payload_index], 2, rtp_payloads[payload_index].Length - 2); // start after NAL Unit Type and FU Header byte
     }
    
     if (fu_header_s == 0)
     {
     // append this payload to the output NAL stream
     // Data starts after the NAL Unit Type byte and the FU Header byte
    
     fs.Write(rtp_payloads[payload_index], 2, rtp_payloads[payload_index].Length-2); // start after NAL Unit Type and FU Header byte
     }
     }
    
     else if (nal_header_type == 29)
     {
     Console.WriteLine("Fragmented Packet FU-B not supported");
     fu_b++;
     }
     else
     {
     Console.WriteLine("Unknown NAL header " + nal_header_type);
     }
    
     }
     // ensure video is written to disk
     fs.Flush(true);
    
     // Print totals
     Console.WriteLine("Norm=" + norm + " ST-A=" + stap_a + " ST-B=" + stap_b + " M16=" + mtap16 + " M24=" + mtap24 + " FU-A=" + fu_a + " FU-B=" + fu_b);
     }
    
Product Versions Compatible and additional computed target framework versions.
.NET net5.0 net5.0 was computed.  net5.0-windows net5.0-windows was computed.  net6.0 net6.0 was computed.  net6.0-android net6.0-android was computed.  net6.0-ios net6.0-ios was computed.  net6.0-maccatalyst net6.0-maccatalyst was computed.  net6.0-macos net6.0-macos was computed.  net6.0-tvos net6.0-tvos was computed.  net6.0-windows net6.0-windows was computed.  net7.0 net7.0 was computed.  net7.0-android net7.0-android was computed.  net7.0-ios net7.0-ios was computed.  net7.0-maccatalyst net7.0-maccatalyst was computed.  net7.0-macos net7.0-macos was computed.  net7.0-tvos net7.0-tvos was computed.  net7.0-windows net7.0-windows was computed.  net8.0 net8.0 is compatible.  net8.0-android net8.0-android was computed.  net8.0-browser net8.0-browser was computed.  net8.0-ios net8.0-ios was computed.  net8.0-maccatalyst net8.0-maccatalyst was computed.  net8.0-macos net8.0-macos was computed.  net8.0-tvos net8.0-tvos was computed.  net8.0-windows net8.0-windows was computed.  net9.0 net9.0 is compatible.  net9.0-android net9.0-android was computed.  net9.0-browser net9.0-browser was computed.  net9.0-ios net9.0-ios was computed.  net9.0-maccatalyst net9.0-maccatalyst was computed.  net9.0-macos net9.0-macos was computed.  net9.0-tvos net9.0-tvos was computed.  net9.0-windows net9.0-windows was computed.  net10.0 net10.0 is compatible.  net10.0-android net10.0-android was computed.  net10.0-browser net10.0-browser was computed.  net10.0-ios net10.0-ios was computed.  net10.0-maccatalyst net10.0-maccatalyst was computed.  net10.0-macos net10.0-macos was computed.  net10.0-tvos net10.0-tvos was computed.  net10.0-windows net10.0-windows was computed. 
.NET Core netcoreapp2.0 netcoreapp2.0 was computed.  netcoreapp2.1 netcoreapp2.1 was computed.  netcoreapp2.2 netcoreapp2.2 was computed.  netcoreapp3.0 netcoreapp3.0 was computed.  netcoreapp3.1 netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 netstandard2.0 is compatible.  netstandard2.1 netstandard2.1 is compatible. 
.NET Framework net461 net461 was computed.  net462 net462 was computed.  net463 net463 was computed.  net47 net47 was computed.  net471 net471 was computed.  net472 net472 was computed.  net48 net48 was computed.  net481 net481 was computed. 
MonoAndroid monoandroid monoandroid was computed. 
MonoMac monomac monomac was computed. 
MonoTouch monotouch monotouch was computed. 
Tizen tizen40 tizen40 was computed.  tizen60 tizen60 was computed. 
Xamarin.iOS xamarinios xamarinios was computed. 
Xamarin.Mac xamarinmac xamarinmac was computed. 
Xamarin.TVOS xamarintvos xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on SharpRTSP:

Package Downloads
SharpRTSPClient

Simple RTSP/RTSPS client and server. Supports H264, H265, H266, AV1 and AAC.

SharpRTSPServer

Simple RTSP/RTSPS client and server. Supports H264, H265, H266, AV1 and AAC.

StreamLayout

Package Description

Colda.CommonUtilities.Communication.RTSP

C# implementation of RTSP communication interface.

MsM.SharpRTSPtoWebRTC

A C# implementation of the RTSP to WebRTC gateway that allows you to stream RTSP from various sources to the web browser. It is implemented in netstandard2.0 without any native dependencies. Suppports H264 and H265 re-streaming (H265 in WebRTC is only available in Safari). Audio transcoding from AAC to Opus is also supported.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.11.1 1,480 5/21/2026
1.11.0 7,675 1/20/2026
1.10.2 1,849 1/3/2026
1.10.1 313 12/31/2025
1.10.0 1,147 12/7/2025
1.9.5 9,766 10/29/2025
1.9.4 423 10/27/2025
1.9.3 870 9/21/2025
1.9.2 1,844 9/9/2025
1.9.1 2,130 8/22/2025
1.9.0 1,123 8/18/2025
1.8.3 918 8/3/2025
1.8.2 971 6/27/2025
1.8.1 2,080 5/26/2025
1.8.0 13,624 11/15/2024
1.7.0 6,477 9/11/2024
1.6.0 483 9/7/2024
1.5.1 831 9/2/2024
1.5.0 675 8/15/2024
1.4.3 4,892 5/14/2024
Loading failed