private async Task RtspReader() { Logger.Info("RtspReader started"); try { if (false == await Connect()) { return; } rtspListener.Start(_rtpRtspCts.Token); RequestOptions(); while (!_rtpRtspCts.IsCancellationRequested && rtspSocket.Connected) { var message = await _rtspChannel.Reader.ReadAsync(_rtpRtspCts.Token); switch (message) { case RtspResponse response: RtspMessageReceived(response); // Exit if response is a result of teardown request. if (response.OriginalRequest is RtspRequestTeardown) { return; } break; case RtspRequest request: RtspRequestReceived(request); break; } } } catch (Exception ex) when(!(ex is TaskCanceledException || ex is OperationCanceledException || ex is ChannelClosedException)) { // Ignorable exceptions listed above Logger.Error(ex); rtspErrorSubject.OnNext($"Error. {ex.Message}"); } finally { // Send EOS PushChunk(null); // Assures EOS is dispatched before termination await Task.Yield(); ProcessTeardownResponse(); Logger.Info("RtspReader stopped"); } }
/// <summary> /// Gets the RTSP listener for destination. /// </summary> /// <param name="destinationUri">The destination URI.</param> /// <returns>An RTSP listener</returns> /// <remarks> /// This method try to get one of openned TCP listener and /// if it does not find it, it create it. /// </remarks> private RtspListener GetRtspListenerForDestination(Uri destinationUri) { Contract.Requires(destinationUri != null); RtspListener destination; string destinationName = destinationUri.Authority; if (_serverListener.ContainsKey(destinationName)) destination = _serverListener[destinationName]; else { destination = new RtspListener( new RtspTcpTransport(destinationUri.Host, destinationUri.Port) ); // un peu pourri mais pas d'autre idée... // pour avoir vraiment des clef avec IP.... if (_serverListener.ContainsKey(destination.RemoteAdress)) destination = _serverListener[destination.RemoteAdress]; else { AddListener(destination); destination.Start(); } } return destination; }
public void Start() { _listener.Start(); }
public volatile RtspStatus CurrentStatus; // Connecting, Connected etc // Constructor public RTSPClient(String url, RTP_TRANSPORT rtp_transport) { Rtsp.RtspUtils.RegisterUri(); Console.WriteLine("Connecting to " + url); this.url = url; // Use URI to extract host, port, username and password Uri uri = new Uri(this.url); if (uri.UserInfo.Length > 0) { try { username = uri.UserInfo.Split(new char[] { ':' })[0]; password = uri.UserInfo.Split(new char[] { ':' })[1]; this.url = uri.GetComponents((UriComponents.AbsoluteUri & ~UriComponents.UserInfo), UriFormat.UriEscaped); uri = new Uri(this.url); } catch { username = null; password = null; } } Rtsp_Client_StatusChanged(this, new RtspStatusEventArgs(RtspStatus.Connecting)); // Connect to a RTSP Server. The RTSP session is a TCP connection try { rtsp_socket = new Rtsp.RtspTcpTransport(uri.Host, uri.Port); } catch { Console.WriteLine("Error - did not connect"); Rtsp_Client_StatusChanged(this, new RtspStatusEventArgs(RtspStatus.ConnectFailed)); return; } if (rtsp_socket.Connected == false) { Console.WriteLine("Error - did not connect"); Rtsp_Client_StatusChanged(this, new RtspStatusEventArgs(RtspStatus.ConnectFailed)); return; } Rtsp_Client_StatusChanged(this, new RtspStatusEventArgs(RtspStatus.Connected)); String now = DateTime.Now.ToString("yyyyMMdd_HHmmss"); if (write_log_files == true) { String filename = "rtsp_capture_" + now + ".264"; fs = new FileStream(filename, FileMode.Create); } if (fs2 == null) { String filename2 = "rtsp_capture_" + now + ".raw"; fs2 = new StreamWriter(filename2); } // Connect a RTSP Listener to the RTSP Socket (or other Stream) to send RTSP messages and listen for RTSP replies rtsp_client = new Rtsp.RtspListener(rtsp_socket); rtsp_client.MessageReceived += Rtsp_MessageReceived; rtsp_client.DataReceived += Rtp_DataReceived; rtsp_client.StatusChanged += Rtsp_Client_StatusChanged; rtsp_client.Start(); // start listening for messages from the server (messages fire the MessageReceived event) // Check the RTP Transport // If the RTP transport is TCP then we interleave the RTP packets in the RTSP stream // If the RTP transport is UDP, we initialise two UDP sockets (one for video, one for RTCP status messages) // If the RTP transport is MULTICAST, we have to wait for the SETUP message to get the Multicast Address from the RTSP server this.rtp_transport = rtp_transport; if (rtp_transport == RTP_TRANSPORT.UDP) { udp_pair = new UDPSocket(50000, 50020); // give a range of 10 pairs (20 addresses) to try incase some address are in use udp_pair.DataReceived += Rtp_DataReceived; udp_pair.Start(); // start listening for data on the UDP ports } if (rtp_transport == RTP_TRANSPORT.TCP) { // Nothing to do. Data will arrive in the RTSP Listener } if (rtp_transport == RTP_TRANSPORT.MULTICAST) { // Nothing to do. Will open Multicast UDP sockets after the SETUP command } // Send OPTIONS // In the Received Message handler we will send DESCRIBE, SETUP and PLAY Rtsp.Messages.RtspRequest options_message = new Rtsp.Messages.RtspRequestOptions(); options_message.RtspUri = new Uri(this.url); rtsp_client.SendMessage(options_message); }
/// <summary> /// Accepts the connection. /// </summary> private void AcceptConnection() { try { while (!_Stopping.WaitOne(0)) { TcpClient oneClient = _RTSPServerListener.AcceptTcpClient(); 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; } }