Giter VIP home page Giter VIP logo

sharprtsp's Introduction

Sharp RTSP

Nuget

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
  • RTP Receiver - will recieve 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 hanlders for H264, H265/HEVC, G711 and AMR are provided.

⚠️ : 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 vdeo (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);
          }

sharprtsp's People

Contributors

bentorkington avatar eyal7773 avatar hepper avatar jimm98y avatar ngraziano avatar phillijw avatar rogerhardiman avatar sheacodes avatar ypenev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sharprtsp's Issues

Thanks!

Just a quick thank you for making and maintaining such a great package! Code is so nice and easy to understand has helped me with countless experiments, thanks again!

RTSP Redirect

I want to set up an RTSP redirect only so I can use a different url for the streams such as rtsp://streams.something.com:554/stream1 will redirect to rtsp://232.232.54.23/stream1. Does this library support such a scenario or can that be accomplished with a web server?

Save each frame into a still image instead of h264 file

Hi Nicolas,

Thanks for sharing this useful library!

A quick question regarding using this library, could it save each frame into a still image instead of .264 file?

Process_RTP_Frame() writes file stream as NAL, How can I extra the image from the raw bytes?

Thanks and regards,
Yong

FFMpeg => RtspMultiplexer return 400 bad request

1、 Start RtspMultiplexer

2、 Use Command: ffmpeg -i CollectionMercy.flv -vcodec copy -acodec copy -
rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554

Server Console:
Image of RtspMultiplexer Console

FFMpeg Console:
Image of Cmd FFMpeg Console

Image of Cmd FFMpeg Console

Could you tell me how to use? Thank you!

Documentation ?

Hi,
Do you plan to add any documentation or implementation example ?

rtp_marker is missing when using proxy live555

Hello,

we encounter an issue when we use live555 proxy for RTSP.
when use it the rtp_marker is always at 0.

we try without using live555 proxy on the same camera and it send us 0 and 1 when it need, but this info is always at 0 when we use the proxy.

thank you for your time.

Samuel

RTP-Info header is missing

The RTSP PLAY response does not include the RTP-Info header. This header includes the initial RTP time stamp and sequence number. It is important, the absence of this header can cause interop problems.
Also the Transport header in the SETUP response should include the ssrc parameter (which specifies the SSRC of the RTP packets.)

How to get frame from RTSP stream?

Good afternoon!
How to create bitmap from an array byte?
I tried to get using this method from the project. No result.
// Output an array of NAL Units.
// One frame of video may encoded in 1 large NAL unit, or it may be encoded in several small NAL units.
// This function writes out all the NAL units that make one frame of video.
// This is done to make it easier to feed H264 decoders which may require all the NAL units for a frame of video at the same time.

    // When writing to a .264 file we will add the Start Code 0x00 0x00 0x00 0x01 before each NAL unit
    // when outputting data for H264 decoders, please note that some decoders require a 32 bit size length header before each NAL unit instead of the Start Code
    private void Output_NAL(List<byte[]> nal_units)
    {
        if (fs == null) return; // check filestream initialised

        int bytes_written = 0;

        foreach (byte[] nal_unit in nal_units)
        {
            fs.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4);  // Write Start Code
            fs.Write(nal_unit, 0, nal_unit.Length);           // Write NAL
                          bytes_written += (nal_unit.Length + 4);
        }
        fs.Flush(true);
    }

RtspClientExample/RTSPClient.cs UDP Socket Port Number Problem

if (rtp_transport == RTP_TRANSPORT.UDP)
{
video_udp_pair = new Rtsp.UDPSocket(40000, 41000); //video_udp_pair = new Rtsp.UDPSocket(50000, 51000);
video_udp_pair.DataReceived += Rtp_DataReceived;
video_udp_pair.Start(); // start listening for data on the UDP ports

            audio_udp_pair = new Rtsp.UDPSocket(50000, 51000); 
            audio_udp_pair.DataReceived += Rtp_DataReceived;
            audio_udp_pair.Start(); // start listening for data on the UDP ports

}

I tested with VLC Stream Server.
VLC Stream Server uses UDP Streaming, so I can find a bug in sample code.

The video_udp_pair Socket Port number is same as the audio_udp_pair Socket Port number.
Can you fix it?

SharpRTSP not working with Janus Gateway

SharpRTSP's CameraExample does not work with Janus. Every other stream i've tested works on Janus.
Is there anything non standard done in SharpRTSP with RTSP streams ? It does work with VLC, live555 RTSP Proxy, KMP, webrtc-streamer (this one transcode from H264 to VP8, Janus does not). I'm struggling with this since a few days, I thought the problem came from UDP (as Janus only support UDP).

Janus' Github: https://github.com/meetecho/janus-gateway

webrtc-streamer's Github: https://github.com/mpromonet/webrtc-streamer

MediaPlayer

So, my idiots question. How can i play rtsp stream in MediaElement uwp?

RTSP server streaming pictures

I have camera taking pictures to directory that I would like to stream. How do I stream jpg files using your RTSP server implementation?

I like very much of your RTSP client and server library. Camera sample works nicely with VLC player.

how to resize video size(width, height) in sps header?

i'm trying to resize video in RTSPCameraExample but it not working then i found that video size has send to rtsp client by sps and pps info, it seem to be too hard for me, please guide me how to resize video header in sps/pps info.

Thank & Best Regards

TcpToUdpForwarder

First of all I would like to say great project...!

I have my own @ https://net7mma.codeplex.com/

Anyway in https://github.com/ngraziano/SharpRTSP/blob/master/RtspMultiplexer/TcpToUdpForwader.cs

You are sending TCP ALF frame headers to the UDP EndPoint...

if (e == null)
throw new ArgumentNullException("e");
Contract.EndContractBlock();
try
{

            RtspData data = e.Message as RtspData;
            if (data != null)
            {
                byte[] frame = data.Data;
                if (data.Channel == this.SourceInterleavedVideo)
                {
                    ForwardVUdpPort.BeginSend(frame, frame.Length, new AsyncCallback(EndSendVideo), frame);
                }
            }
        }
        catch (Exception error)
        {

            _logger.Warn("Error during frame forwarding", error);
        }

Should be something like

if (e == null)
throw new ArgumentNullException("e");
Contract.EndContractBlock();
try
{

            RtspData data = e.Message as RtspData;
            if (data != null)
            {
                byte[] frame = data.Data;
                if (data.Channel == this.SourceInterleavedVideo)
                {

//Don't send TCP ALF to UDP EndPoints, Only skip when not sending a 'chunk' of a frame...
ForwardVUdpPort.BeginSend(frame, 4, frame.Length - 4, new AsyncCallback(EndSendVideo), frame);
}
}
}
catch (Exception error)
{

            _logger.Warn("Error during frame forwarding", error);
        }

You might also have to move the 'State' to the RtspData class so you would be able to check if it's part of a 'JUMBO' Frame or not... e.g. if you are Receiving 65535 and the chunk received is not complete and only has 65000 bytes of data you may have to combined it with the next chunk and not skip the ALF offset...

Viva la resistance~!

v//

Add RTP Header extension

Hi,

I've been trying to add a header extension in the CCTV RTSP camera and client example without any luck so far. Have anyone made a working example of this?

I'm trying to add custom metadata to the h264 stream.

The frame rate of the recorded video becomes high.

Hello.
I am using the RTSP Client Example to record the video of the network camera.
.264 file is generated, but the speed of the video is about 30 times.
Camera images are output at 1 fps, but in the generated file it is 25 to 30 fps.
Do you know what is wrong?

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

I'm using ShartRTSP to connect to HIPCAM camera by rtsp protocol.
The handshake of rtsp is so well and I receive packet from rtsp server. But around 1 or 2 minutes later SharpRTSP cannot get data from network.
I try to print out the debug message and see that the SharpRTSP send GET_PARAMETER every timeout / 2 interval. But without OK message response , SharpRTSP continue to send GET_PARAMETER again and this cause the problem.
Please take a look the debug message in the attached file.
rtspinfo.txt

How to handle mjpeg RTSP stream?

I got a mjpeg rtsp stream. How can I extract and export the frame data?

the sdp data of the stream

v=0
o=- 11814266 1 IN IP4 192.168.1.169
s=RTSP/RTP stream from IPNC
i=mjpeg
t=0 0
a=tool:LIVE555 Streaming Media v2015.08.07
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:RTSP/RTP stream from IPNC
a=x-qt-text-inf:mjpeg
m=video 0 RTP/AVP 26
c=IN IP4 0.0.0.0
b=AS:12000
a=control:track1

Play message in RtspClientExample is missing authorization

Hi Nicolas,
Thank you for sharing this great library!

It seems like there is a small error in the RtspClientExample . I have an AXIS IP camera which requires user/pwd authorization. The example code was giving me a 401 error after sending the PLAY request.

I added a "digest_authorization" string to the "play_message" header and now it works perfectly.

exception handling

I'm sorry, my English is not good
Can add an exception handling

eg:
c.Received_Error += exception => {
// exception handling
}

Unable to playback rtsp streams using 3rd party players

Hi

This is a great project and has helped me begin to learn the concepts of Rtsp server especially around the messaging.

My colleague and I are both looking at using this project to see if we can host our external ffmpeg encoded h264 stream, and have 3rd party players also, to playback this stream.

We can playback our h264 stream using the RtspClientExample and using ffplay to play the output .264 file.

But we cannot playback PULL stream using 3rd party players such as VLC or ffmediaElement as we need to have a solution that allows any client including 3rd partys to playback the stream.

This is my ffmpeg code:

.\ffmpeg -protocol_whitelist file,udp,rtp -re -i camera99.sdp -vcodec copy -muxdelay 0.1 -threads 4 -sc_threshold 0 -rtsp_transport udp -f rtsp rtsp://127.0.0.1:8554/PUSH/myStream

I don't know how to playback this stream using 3rd party players such as VLC or ffmediaElement ??

Sending RGB images

Hi,

I try to send the stream of a local webcam. To do so, I converted every image from RGB to YUV an stored the resulting picture in a byte array. I used the resulting array to replace the suv_data byte array from the RTSPCameraExample to send this via the rtsp stream.
When I open the resulting stream the image doesn't seem to be the original image.
Is there any problem when converting rgb images and use them for the stream?

how to show streaming this images on VLC with RTSP.

Hi,

I build project RtspCameraExample success and then I open connect to rtsp://10.30.176.31:8554 via VLC
I think it will show live images YUV type - same video, that project generate from code.
However VLC nothing show any thing,
So could you help how to show streaming this images on VLC with RTSP.

Thanks and Best Regards!

(Not issue) Suggestion to use different h264 encoder

Hello,
I am using ShartRTSP to create an RTSP server.
RtspCameraExample works out-of-the-box: it is nice and clear.

About encoders:

  • Tiny: resolution limited to 192x128
  • Simple: lossless and seems to create too large UDP dataframe with higher resolution, so it fails.
    UDP Write Exception System.Net.Sockets.SocketException (0x80004005): A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself

Therefore I would like to use it with a lossy h264 encoder on Windows, but I don't know what to look for or how to do.
Any suggestions / examples / suggested libraries / Nugets / documents to read about?

Thank you

Publish stream

Hi! Is it possibile, with this library, to publish rtsp stream to a RTSP server?

UDP Support implementation

Hi,

I am using SharpRTSP to create RTSP streams (using the example RtspCameraExample).
Sadly I need UDP support too, and I am looking where to add it.

I think what is missing is an implementation of IRTSPTransport, like RTSPTCPTransport but for UDP.

In the file RtspServer.cs, we got this :

private void AcceptConnection()
    {
        try
        {
            while (!_Stopping.WaitOne(0))
            {
                TcpClient oneClient = _RTSPServerListener.AcceptTcpClient();
                Console.WriteLine("Connection from " + oneClient.Client.RemoteEndPoint.ToString());

                var rtsp_socket = new RtspTcpTransport(oneClient);
                RtspListener newListener = new RtspListener(rtsp_socket);
                newListener.MessageReceived += RTSP_Message_Received;
                //RTSPDispatcher.Instance.AddListener(newListener);
                newListener.Start();
            }
        }
        catch (SocketException error)
        {
            // _logger.Warn("Got an error listening, I have to handle the stopping which also throw an error", error);
        }
        catch (Exception error)
        {
            // _logger.Error("Got an error listening...", error);
            throw;
        }


    }

This seems to be the code that accepts a newly connected client. From what I understood, it assumes that the client is using TCP before the RTSP message exchange.

Am I on the right way ? Do you have any additional informations that could be useful ?

Thanks

Rtsp Basic authorisation

If camera supportst only "Basic" authorisation, RtspClientExample does not work. You should check for "Basic" in Rtsp_MessageReceived (message looks like: "WWW-Authenticate: Basic realm="xxxxxxx"...). We could extend 'GenerateDigestAuthorisation' like this:
` // Generate Digest Authorization
public string GenerateDigestAuthorization(string username, string password,
string realm, string nonce, string url, string command, bool basic) {

        if (username == null || username.Length == 0) return null;
        if (password == null || password.Length == 0) return null;
        if (realm == null || realm.Length == 0) return null;
        if (basic == true) return ("Basic " + System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password)));`

Stop record at X frames

Hi, how can I calculate the amount of frame that has already been recorded in the physical file? Inside the event 'RTSPClient.Received_NALs_Delegate (c_Received_NALs)' and after having recorded X frames, close the connection with the camera?

tkx advanced!

make "describeResponse" available as member

Within describeResponse the SDP is read and parsed.

I see no way to get o not parsed information.

For example: I need the of
a=framerate:XX
because the fr is not always provided with the SPS

Authentication problem

Hi
in my camera setup I have an option "Enable RTSP connection without authentication" when enable this option program runs correctly but when disable DESCRIBE message return 401 code ("Unauthorized")
how can I set UserName and Password in commands?

NuGet Support?

Surprised this project doesn't have it, is there some reason?

Can you help me in extending to get the eventId,endOfEvent,reserved,volume,eventduration fields

I see in the RTSP Client Example
We can extend the following part
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
      }

to get the eventId and endofEvent and such things.
Since you must be having better knowledge

What all you say?

Stream webcam in HD

Hello,

I've two questions:
-How to stream a webcam source ?
-Is it possible to stream in a 1080p resolution for a production stage website ?

Thank you !

webapi2 PushContentStream

I am finding a solution to live stream video from RTP/RSTP. How can we combine this with PushContentStream? So in Received_SPS_PPS, Received_NALs, ... instead of store binary to files, just convert to streamable binary and write it to http response?

VLC Server Test

Looking at the RtspClientExample it shows a test url of:

        // VLC Server Tests
        // String url = "rtsp://192.168.1.150:8554/test";

Could you let me know how you have VLC server configured at the command line to allow the connection please?

Authorization and setup

Hi @ngraziano. Thanks for this great library! I have the following use case and wondering where to start:

  1. User selects a CCTV RTSP video stream.
  2. We authenticate against that camera with username/password.
  3. Return stream to the user's browser via WebAPI.
  4. User can play the stream in an HTML5 video player.

Is this possible with SharpRTSP? Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.