Ejemplo n.º 1
0
        /// <summary>
        /// Selects the transport based on the configuration of the system..
        /// </summary>
        /// <param name="requestSetup">The request setup message.</param>
        /// <returns>The selected transport</returns>
        /// <remarks>
        /// The transport is selected by taking the first supported transport
        /// in order of appearence.
        /// </remarks>
        private static RtspTransport SelectTransport(RtspRequestSetup requestSetup)
        {
            RtspTransport selectedTransport  = null;
            const bool    acceptTCP          = false;
            const bool    acceptUDPUnicast   = true;
            const bool    acceptUDPMulticast = true;

            foreach (RtspTransport proposedTransport in requestSetup.GetTransports())
            {
                if (acceptTCP && proposedTransport.LowerTransport == RtspTransport.LowerTransportType.TCP)
                {
                    selectedTransport = proposedTransport;
                    break;
                }
                if (acceptUDPMulticast && proposedTransport.LowerTransport == RtspTransport.LowerTransportType.UDP &&
                    proposedTransport.IsMulticast)
                {
                    selectedTransport = proposedTransport;
                    break;
                }
                if (acceptUDPUnicast && proposedTransport.LowerTransport == RtspTransport.LowerTransportType.UDP &&
                    !proposedTransport.IsMulticast)
                {
                    selectedTransport = proposedTransport;
                    break;
                }
            }
            return(selectedTransport);
        }
Ejemplo n.º 2
0
        internal RtspResponse HandlePullSetup(RtspRequestSetup request)
        {
            var response = request.CreateResponse();

            if (string.IsNullOrEmpty(response.Session))
            {
                // TODO Allocate a real session ID
                response.Session = sessionGenerator.Next().ToString();
            }

            var pushUri = GetPushUri(request.RtspUri.AbsolutePath);

            RtspPushDescription description;

            if (PushDescriptions.TryGetValue(pushUri, out description))
            {
                //TODO get port and multicast address from description.
                var forwarder = description.GetForwarderFor(pushUri);
                var transport = new RtspTransport();

                RtspTransport newTransport = new RtspTransport()
                {
                    IsMulticast = true,
                    Destination = forwarder.ForwardHostVideo,
                    Port        = new PortCouple(forwarder.ForwardPortVideo, forwarder.ListenCommandPort)
                };
                response.Headers[RtspHeaderNames.Transport] = newTransport.ToString();
            }
            else
            {
                response.ReturnCode = 404;
            }
            return(response);
        }
Ejemplo n.º 3
0
        private void ProcessDescribeResponse(RtspResponse message)
        {
            // Got a reply for DESCRIBE
            // Examine the SDP
            Logger.Info(System.Text.Encoding.UTF8.GetString(message.Data));

            Rtsp.Sdp.SdpFile sdpData;
            using (StreamReader sdpStream = new StreamReader(new MemoryStream(message.Data)))
            {
                sdpData = Rtsp.Sdp.SdpFile.Read(sdpStream);
            }

            // Process each 'Media' Attribute in the SDP (each sub-stream)
            // If the attribute is for Video, then carry out a SETUP and a PLAY
            // Only do this for the first Video attribute in case there is more than one in the SDP
            for (int x = 0; x < sdpData.Medias.Count; x++)
            {
                if (sdpData.Medias[x].MediaType == Media.MediaTypes.video)
                {
                    // We only want the first video sub-stream
                    if (videoPayloadType != -1)
                    {
                        return;
                    }

                    // search the attributes for control, fmtp and rtpmap
                    ParseAttributes(sdpData, x, out string control, out Rtsp.Sdp.AttributFmtp fmtp, out Rtsp.Sdp.AttributRtpMap rtpmap);

                    // Split the fmtp to get the sprop-parameter-sets which hold the SPS and PPS in base64
                    if (fmtp != null)
                    {
                        var param = Rtsp.Sdp.H264Parameters.Parse(fmtp.FormatParameter);
                        OutputNal(param.SpropParameterSets); // output SPS and PPS
                    }

                    // Split the rtpmap to get the Payload Type
                    videoPayloadType = 0;
                    if (rtpmap != null)
                    {
                        videoPayloadType = rtpmap.PayloadNumber;
                    }

                    RtspRequestSetup setupMessage = new RtspRequestSetup();
                    setupMessage.RtspUri = new Uri(rtspUrl + "/" + control);

                    var transport = GetRTSPTransport();
                    setupMessage.AddTransport(transport);

                    PostRequest(setupMessage);
                }
            }
        }
Ejemplo n.º 4
0
        internal RtspResponse HandleSetup(RtspRequestSetup request)
        {
            Contract.Requires(request != null);
            Contract.Ensures(Contract.Result <RtspResponse>() != null);

            var response = request.CreateResponse();

            if (string.IsNullOrEmpty(response.Session))
            {
                // TODO Allocate a real session ID
                response.Session = sessionGenerator.Next().ToString();
            }

            RtspPushDescription description;

            if (!PushDescriptions.TryGetValue(request.RtspUri.AbsolutePath, out description))
            {
                response.ReturnCode = 404;
                return(response);
            }


            bool configok = false;

            foreach (var transport in request.GetTransports())
            {
                if (transport.LowerTransport == RtspTransport.LowerTransportType.UDP &&
                    !transport.IsMulticast
                    )
                {
                    var forwarder = new UDPForwarder();
                    description.AddForwarders(response.Session, request.RtspUri.AbsolutePath, forwarder);
                    transport.ServerPort = new PortCouple(forwarder.ListenVideoPort);
                    response.Headers[RtspHeaderNames.Transport] = transport.ToString();
                    configok = true;
                }
            }

            if (!configok)
            {
                response.ReturnCode = 461;
            }
            return(response);
        }
Ejemplo n.º 5
0
        private void RTSP_ProcessSetupRequest(RtspRequestSetup message, RtspListener listener)
        {
            //
            var setupMessage = message;

            // Check the RTSP transport
            // If it is UDP or Multicast, create the sockets
            // If it is RTP over RTSP we send data via the RTSP Listener

            // FIXME client may send more than one possible transport.
            // very rare
            RtspTransport transport = setupMessage.GetTransports()[0];


            // Construct the Transport: reply from the Server to the client
            Rtsp.UDPSocket udp_pair;
            RtspTransport  transport_reply   = RTSP_ConstructReplyTransport(transport, out udp_pair);
            bool           mediaTransportSet = false;

            if (transport_reply != null)
            {
                // Update the session with transport information
                String copy_of_session_id = "";

                // ToDo - Check the Track ID to determine if this is a SETUP for the Video Stream
                // or a SETUP for an Audio Stream.
                // In the SDP the H264 video track is TrackID 0

                // Add the transports to the connection

                if (contentBase != null)
                {
                    string controlTrack = setupMessage.RtspUri.AbsoluteUri.Replace(contentBase, string.Empty);
                    var    requestMedia = _sdpFile.Medias.FirstOrDefault(media =>
                                                                         media.Attributs.FirstOrDefault(a => a.Key == "control" &&
                                                                                                        (a.Value == controlTrack || "/" + a.Value == controlTrack)) != null);

                    if (requestMedia != null)
                    {
                        if (requestMedia.MediaType == Media.MediaTypes.video)
                        {
                            _videoClientTransport = transport;
                            _videoTransportReply  = transport_reply;

                            // If we are sending in UDP mode, add the UDP Socket pair and the Client Hostname
                            if (_videoUdpPair != null)
                            {
                                ReleaseUDPSocket(_videoUdpPair);
                            }
                            _videoUdpPair     = udp_pair;
                            mediaTransportSet = true;

                            if (setupMessage.Session == null)
                            {
                                _videoSessionId = _sessionHandle.ToString();
                                _sessionHandle++;
                            }
                            else
                            {
                                _videoSessionId = setupMessage.Session;
                            }



                            // Copy the Session ID
                            copy_of_session_id = _videoSessionId;
                        }

                        if (requestMedia.MediaType == Media.MediaTypes.audio)
                        {
                            _audioClientTransport = transport;
                            _audioTransportReply  = transport_reply;

                            // If we are sending in UDP mode, add the UDP Socket pair and the Client Hostname
                            if (_audioUdpPair != null)
                            {
                                ReleaseUDPSocket(_audioUdpPair);
                            }
                            _audioUdpPair     = udp_pair;
                            mediaTransportSet = true;


                            if (setupMessage.Session == null)
                            {
                                _audioSessionId = _sessionHandle.ToString();
                                _sessionHandle++;
                            }
                            else
                            {
                                _audioSessionId = setupMessage.Session;
                            }

                            // Copy the Session ID
                            copy_of_session_id = _audioSessionId;
                        }
                    }
                }

                if (false == mediaTransportSet)
                {
                    Rtsp.Messages.RtspResponse setup_response = setupMessage.CreateResponse(_logger);
                    // unsuported mediatime
                    setup_response.ReturnCode = 415;
                    listener.SendMessage(setup_response);
                }
                else
                {
                    Rtsp.Messages.RtspResponse setup_response = setupMessage.CreateResponse(_logger);
                    setup_response.Headers[Rtsp.Messages.RtspHeaderNames.Transport] = transport_reply.ToString();
                    setup_response.Session = copy_of_session_id;
                    setup_response.Timeout = timeout_in_seconds;
                    listener.SendMessage(setup_response);
                }
            }
            else
            {
                Rtsp.Messages.RtspResponse setup_response = setupMessage.CreateResponse(_logger);
                // unsuported transport
                setup_response.ReturnCode = 461;
                listener.SendMessage(setup_response);
            }

            if (false == mediaTransportSet)
            {
                if (udp_pair != null)
                {
                    ReleaseUDPSocket(udp_pair);
                    udp_pair = null;
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Handles a request setup.
        /// </summary>
        /// <param name="destination">The destination.</param>
        /// <param name="requestSetup">The request setup.</param>
        /// <returns>The rewritten message</returns>
        /// <remarks>
        /// The destination can be modified.
        /// </remarks>
        private RtspMessage HandleRequestSetup(ref RtspListener destination, RtspRequestSetup requestSetup)
        {
            Contract.Requires(requestSetup != null);
            Contract.Requires(destination != null);
            Contract.Ensures(Contract.Result <RtspMessage>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out destination) != null);


            // look if we already have a multicast streaming playing for this URI.
            foreach (var session in _activesSession.Values)
            {
                if (session.State == RtspSession.SessionState.Playing && session.ListOfForwader.ContainsKey(requestSetup.RtspUri))
                {
                    Forwarder existingForwarder = session.ListOfForwader[requestSetup.RtspUri];
                    if (existingForwarder != null && existingForwarder.ToMulticast)
                    {
                        RtspResponse returnValue = requestSetup.CreateResponse();
                        returnValue.Headers[RtspHeaderNames.Transport] = new RtspTransport()
                        {
                            IsMulticast = true,
                            Destination = existingForwarder.ForwardHostVideo,
                            Port        = new PortCouple(existingForwarder.ForwardPortVideo, existingForwarder.ListenCommandPort),
                        }.ToString();
                        returnValue.Session = session.Name;
                        destination         = requestSetup.SourcePort;
                        return(returnValue);
                    }
                }
            }


            string setupKey = requestSetup.SourcePort.RemoteAdress + "SEQ" + requestSetup.CSeq.ToString(CultureInfo.InvariantCulture);

            RtspTransport selectedTransport = SelectTransport(requestSetup);

            // We do not handle asked transport so return directly.
            if (selectedTransport == null)
            {
                _logger.Info("No transport asked are supported, sorry");
                RtspResponse returnValue = requestSetup.CreateResponse();
                // Unsupported transport;
                returnValue.ReturnCode = 461;
                destination            = requestSetup.SourcePort;
                return(returnValue);
            }

            UDPForwarder forwarder = new UDPForwarder();

            forwarder.ToMulticast = selectedTransport.IsMulticast;

            // this part of config is only valid in unicast.
            if (!selectedTransport.IsMulticast)
            {
                forwarder.ForwardPortVideo  = selectedTransport.ClientPort.First;
                forwarder.SourcePortCommand = selectedTransport.ClientPort.Second;

                // If the client did not set the destination.. get it from TCP source
                if (!string.IsNullOrEmpty(selectedTransport.Destination))
                {
                    forwarder.ForwardHostVideo = selectedTransport.Destination;
                }
                else
                {
                    forwarder.ForwardHostVideo = requestSetup.SourcePort.RemoteAdress.Split(':')[0];
                    _logger.Debug("Destination get from TCP port {0}", forwarder.ForwardHostVideo);
                }
            }

            // Configured the transport asked.
            forwarder.ForwardHostCommand = destination.RemoteAdress.Split(':')[0];
            RtspTransport firstNewTransport = new RtspTransport()
            {
                IsMulticast = false,
                ClientPort  = new PortCouple(forwarder.ListenVideoPort, forwarder.FromForwardCommandPort),
            };

            RtspTransport secondTransport = new RtspTransport()
            {
                IsMulticast    = false,
                LowerTransport = RtspTransport.LowerTransportType.TCP,
            };

            requestSetup.Headers[RtspHeaderNames.Transport] = firstNewTransport.ToString() + ", " + secondTransport.ToString();
            requestSetup.Headers[RtspHeaderNames.Transport] = firstNewTransport.ToString();// +", " + secondTransport.ToString();
            _setupForwarder.Add(setupKey, forwarder);

            return(requestSetup);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Handles request message.
        /// </summary>
        /// <param name="message">A message, can be rewriten.</param>
        /// <returns>The destination</returns>
        private RtspListener HandleRequest(ref RtspMessage message)
        {
            Contract.Requires(message != null);
            Contract.Requires(message is RtspRequest);
            Contract.Ensures(Contract.Result <RtspListener>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out message) != null);


            RtspRequest request = message as RtspRequest;

            RtspListener destination;

            // Do not forward, direct respond because we do not know where to send.
            if (request.RtspUri == null || request.RtspUri.AbsolutePath.Split(new char[] { '/' }, 3).Length < 3)
            {
                destination = HandleRequestWithoutUrl(ref message);
            }
            else
            {
                try
                {
                    // get the real destination
                    request.RtspUri = RewriteUri(request.RtspUri);
                    destination     = GetRtspListenerForDestination(request.RtspUri);

                    // Handle setup
                    RtspRequestSetup requestSetup = request as RtspRequestSetup;
                    if (requestSetup != null)
                    {
                        message = HandleRequestSetup(ref destination, requestSetup);
                    }

                    //Handle Play Reques
                    RtspRequestPlay requestPlay = request as RtspRequestPlay;
                    if (requestPlay != null)
                    {
                        message = HandleRequestPlay(ref destination, requestPlay);
                    }



                    //Update session state and handle special message
                    if (request.Session != null && request.RtspUri != null)
                    {
                        string sessionKey = RtspSession.GetSessionName(request.RtspUri, request.Session);
                        if (_activesSession.ContainsKey(sessionKey))
                        {
                            _activesSession[sessionKey].Handle(request);
                            switch (request.RequestTyped)
                            {
                            // start here to start early
                            //case RtspRequest.RequestType.PLAY:
                            // _activesSession[sessionKey].Start(request.SourcePort.RemoteAdress);
                            //   break;
                            case RtspRequest.RequestType.TEARDOWN:
                                _activesSession[sessionKey].Stop(request.SourcePort.RemoteAdress);
                                if (!_activesSession[sessionKey].IsNeeded)
                                {
                                    _activesSession.Remove(sessionKey);
                                }
                                else
                                {
                                    // system still need the server to send data do not send him the message.
                                    // reponds to client directly.
                                    destination = request.SourcePort;
                                    message     = request.CreateResponse();
                                }
                                break;
                            }
                        }
                        else
                        {
                            _logger.Warn("Command {0} for session {1} which was not found", request.RequestTyped, sessionKey);
                        }
                    }
                }
                catch (Exception error)
                {
                    _logger.Error("Error during handle of request", error);
                    destination = request.SourcePort;
                    RtspResponse theDirectResponse = request.CreateResponse();
                    theDirectResponse.ReturnCode = 500;
                    message = theDirectResponse;
                }
            }

            return(destination);
        }
Ejemplo n.º 8
0
        // RTSP Messages are OPTIONS, DESCRIBE, SETUP, PLAY etc
        void Rtsp_MessageReceived(object sender, RtspChunkEventArgs e)
        {
            var message = e.Message as RtspResponse;

            //logger.Debug ("Received " + message.OriginalRequest.Method);

            // If message has a 401 - Unauthorised Error, then we re-send the message with Authorization
            // using the most recently received 'realm' and 'nonce'
            if (!message.IsOk)
            {
                logger.Warn("Got Error in RTSP Reply " + message.ReturnCode + " " + message.ReturnMessage);

                if (message.ReturnCode == 401 && (message.OriginalRequest.Headers.ContainsKey(RtspHeaderNames.Authorization) == true))
                {
                    // the authorization failed.
                    Stop();
                    return;
                }

                // Check if the Reply has an Authenticate header.
                if (message.ReturnCode == 401 && message.Headers.ContainsKey(RtspHeaderNames.WWWAuthenticate))
                {
                    // Process the WWW-Authenticate header
                    // EG:   Basic realm="AProxy"
                    // EG:   Digest realm="AXIS_WS_ACCC8E3A0A8F", nonce="000057c3Y810622bff50b36005eb5efeae118626a161bf", stale=FALSE

                    string    www_authenticate = message.Headers [RtspHeaderNames.WWWAuthenticate];
                    string [] items            = www_authenticate.Split(new char [] { ',', ' ' });

                    foreach (string item in items)
                    {
                        if (item.ToLower().Equals("basic"))
                        {
                            auth_type = "Basic";
                        }
                        else if (item.ToLower().Equals("digest"))
                        {
                            auth_type = "Digest";
                        }
                        else
                        {
                            // Split on the = symbol and update the realm and nonce
                            string [] parts = item.Split(new char [] { '=' }, 2);                              // max 2 parts in the results array
                            if (parts.Count() >= 2 && parts [0].Trim().Equals("realm"))
                            {
                                realm = parts [1].Trim(new char [] { ' ', '\"' });                                  // trim space and quotes
                            }
                            else if (parts.Count() >= 2 && parts [0].Trim().Equals("nonce"))
                            {
                                nonce = parts [1].Trim(new char [] { ' ', '\"' });                                  // trim space and quotes
                            }
                        }
                    }

                    //logger.Debug ("WWW Authorize parsed for " + auth_type + " " + realm + " " + nonce);
                }

                var resend_message = message.OriginalRequest.Clone() as RtspMessage;

                if (auth_type != null)
                {
                    AddAuthorization(resend_message, Username, Password, auth_type, realm, nonce, Url);
                }

                rtsp_client.SendMessage(resend_message);

                return;
            }

            // If we get a reply to OPTIONS then start the Keepalive Timer and send DESCRIBE
            if (message.OriginalRequest != null && message.OriginalRequest is RtspRequestOptions)
            {
                string public_methods = message.Headers [RtspHeaderNames.Public];

                SupportedMethods.Clear();

                foreach (string method in public_methods.Split(','))
                {
                    SupportedMethods.Add(method.Trim());
                }

                if (keepalive_timer == null)
                {
                    // Start a Timer to send an OPTIONS command (for keepalive) every 20 seconds
                    keepalive_timer          = new System.Timers.Timer();
                    keepalive_timer.Elapsed += Timer_Elapsed;
                    keepalive_timer.Interval = 5 * 1000;
                    keepalive_timer.Enabled  = true;

                    // Send DESCRIBE
                    var describe_message = new RtspRequestDescribe();
                    describe_message.RtspUri = new Uri(Url);
                    describe_message.AddAccept("application/sdp");

                    if (auth_type != null)
                    {
                        AddAuthorization(describe_message, Username, Password, auth_type, realm, nonce, Url);
                    }

                    rtsp_client.SendMessage(describe_message);
                }
            }

            // If we get a reply to DESCRIBE (which was our second command), then prosess SDP and send the SETUP
            if (message.OriginalRequest != null && message.OriginalRequest is Mictlanix.DotNet.Rtsp.Messages.RtspRequestDescribe)
            {
                // Got a reply for DESCRIBE
                if (!message.IsOk)
                {
                    logger.Warn("Got Error in DESCRIBE Reply " + message.ReturnCode + " " + message.ReturnMessage);
                    return;
                }

                // Examine the SDP
                //logger.Debug (Encoding.UTF8.GetString (message.Data));

                Sdp.SdpFile sdp_data;
                using (var sdp_stream = new StreamReader(new MemoryStream(message.Data))) {
                    sdp_data = Sdp.SdpFile.Read(sdp_stream);
                }

                // Process each 'Media' Attribute in the SDP (each sub-stream)
                for (int x = 0; x < sdp_data.Medias.Count; x++)
                {
                    bool video = (sdp_data.Medias [x].MediaType == Mictlanix.DotNet.Rtsp.Sdp.Media.MediaTypes.video);

                    if (video && video_payload != -1)
                    {
                        continue;                                                   // have already matched an video payload
                    }
                    if (video)
                    {
                        // search the attributes for control, rtpmap and fmtp
                        // (fmtp only applies to video)
                        string            control = "";               // the "track" or "stream id"
                        Sdp.FmtpAttribute fmtp    = null;             // holds SPS and PPS in base64 (h264 video)

                        foreach (var attrib in sdp_data.Medias[x].Attributs)
                        {
                            if (attrib.Key.Equals("control"))
                            {
                                string sdp_control = attrib.Value;
                                if (sdp_control.ToLower().StartsWith("rtsp://", StringComparison.Ordinal))
                                {
                                    control = sdp_control;                                     //absolute path
                                }
                                else if (message.Headers.ContainsKey(RtspHeaderNames.ContentBase))
                                {
                                    control = message.Headers [RtspHeaderNames.ContentBase] + sdp_control;                                     // relative path
                                }
                                else
                                {
                                    control = Url + "/" + sdp_control;                                     // relative path
                                }
                            }
                            if (attrib.Key.Equals("fmtp"))
                            {
                                fmtp = attrib as Sdp.FmtpAttribute;
                            }
                            if (attrib.Key.Equals("rtpmap"))
                            {
                                var rtpmap = attrib as Sdp.RtpMapAttribute;

                                // Check if the Codec Used (EncodingName) is one we support
                                string [] valid_video_codecs = { "H264" };

                                if (video && Array.IndexOf(valid_video_codecs, rtpmap.EncodingName) >= 0)
                                {
                                    // found a valid codec
                                    video_codec   = rtpmap.EncodingName;
                                    video_payload = sdp_data.Medias [x].PayloadType;
                                }
                            }
                        }

                        // If the rtpmap contains H264 then split the fmtp to get the sprop-parameter-sets which hold the SPS and PPS in base64
                        if (video && video_codec.Contains("H264") && fmtp != null)
                        {
                            var param   = Sdp.H264Parameters.Parse(fmtp.FormatParameter);
                            var sps_pps = param.SpropParameterSets;
                            if (sps_pps.Count() >= 2)
                            {
                                byte [] sps = sps_pps [0];
                                byte [] pps = sps_pps [1];
                                ParameterSetsReceived?.Invoke(sps, pps);
                            }
                        }

                        // Send the SETUP RTSP command if we have a matching Payload Decoder
                        if (video && video_payload == -1)
                        {
                            continue;
                        }

                        // Server interleaves the RTP packets over the RTSP connection
                        // TCP mode (RTP over RTSP)   Transport: RTP/AVP/TCP;interleaved=0-1
                        video_data_channel = 0;
                        video_rtcp_channel = 1;

                        var transport = new RtspTransport()
                        {
                            LowerTransport = RtspTransport.LowerTransportType.TCP,
                            Interleaved    = new PortCouple(video_data_channel, video_rtcp_channel),                           // Eg Channel 0 for video. Channel 1 for RTCP status reports
                        };

                        // Send SETUP
                        var setup_message = new RtspRequestSetup();
                        setup_message.RtspUri = new Uri(control);
                        setup_message.AddTransport(transport);

                        if (auth_type != null)
                        {
                            AddAuthorization(setup_message, Username, Password, auth_type, realm, nonce, Url);
                        }

                        rtsp_client.SendMessage(setup_message);
                    }
                }
            }

            // If we get a reply to SETUP (which was our third command), then process and then send PLAY
            if (message.OriginalRequest != null && message.OriginalRequest is RtspRequestSetup)
            {
                // Got Reply to SETUP
                if (!message.IsOk)
                {
                    logger.Warn("Got Error in SETUP Reply " + message.ReturnCode + " " + message.ReturnMessage);
                    return;
                }

                //logger.Debug ("Got reply from SETUP Session=" + message.Session);

                RtspSession = message.Session;                 // Session value used with Play, Pause, Teardown

                // Send PLAY
                RtspRequest play_message = new RtspRequestPlay();
                play_message.RtspUri = new Uri(Url);
                play_message.Session = RtspSession;

                if (auth_type != null)
                {
                    AddAuthorization(play_message, Username, Password, auth_type, realm, nonce, Url);
                }

                rtsp_client.SendMessage(play_message);
            }

            // If we get a reply to PLAY (which was our fourth command), then we should have video being received
            if (message.OriginalRequest != null && message.OriginalRequest is RtspRequestPlay)
            {
                // Got Reply to PLAY
                if (!message.IsOk)
                {
                    logger.Warn("Got Error in PLAY Reply " + message.ReturnCode + " " + message.ReturnMessage);
                    return;
                }

                //logger.Debug ("Got reply from PLAY " + message.Command);
            }
        }
Ejemplo n.º 9
0
        private void MessageReceived(object sender, RtspChunkEventArgs e)
        {
            RtspResponse message = e.Message as RtspResponse;

            // If we get a reply to OPTIONS then start the Keepalive Timer and send DESCRIBE
            if (message.OriginalRequest != null && message.OriginalRequest is RtspRequestOptions)
            {
                // Start a Timer to send an Keepalive RTSP command every 20 seconds
                _keepaliveTimer          = new Timer();
                _keepaliveTimer.Elapsed += SendKeepalive;
                _keepaliveTimer.Interval = 20 * 1000;
                _keepaliveTimer.Enabled  = true;

                // Send DESCRIBE
                RtspRequest describe_message = new RtspRequestDescribe();
                describe_message.RtspUri = new Uri(_url);
                _client.SendMessage(describe_message);
            }


            if (message.OriginalRequest != null && message.OriginalRequest is RtspRequestDescribe)
            {
                Rtsp.Sdp.SdpFile sdp_data;
                using (StreamReader sdp_stream = new StreamReader(new MemoryStream(message.Data)))
                {
                    sdp_data = Rtsp.Sdp.SdpFile.Read(sdp_stream);
                }

                Uri video_uri = null;
                foreach (Rtsp.Sdp.Attribut attrib in sdp_data.Medias[0].Attributs)
                {
                    if (attrib.Key.Equals("control"))
                    {
                        video_uri = new Uri(attrib.Value);
                    }
                }

                RtspTransport transport = new RtspTransport()
                {
                    LowerTransport = RtspTransport.LowerTransportType.TCP,
                    Interleaved    = new PortCouple(0, 1),
                };

                // Generate SETUP messages
                RtspRequestSetup setup_message = new RtspRequestSetup();
                setup_message.RtspUri = video_uri;
                setup_message.AddTransport(transport);

                _client.SendMessage(setup_message);
            }


            if (message.OriginalRequest != null && message.OriginalRequest is RtspRequestSetup)
            {
                if (message.Timeout > 0 && message.Timeout > _keepaliveTimer.Interval / 1000)
                {
                    _keepaliveTimer.Interval = message.Timeout * 1000 / 2;
                }

                // Send PLAY
                RtspRequest play_message = new RtspRequestPlay();
                play_message.RtspUri = new Uri(_url);
                play_message.Session = message.Session;
                _client.SendMessage(play_message);
            }
        }