Exemple #1
0
        public async Task ConnectAsync(DateTime initialTimeStamp, CancellationToken token)
        {
            IRtspTransportClient rtspTransportClient = _transportClientProvider();

            Volatile.Write(ref _rtspTransportClient, rtspTransportClient);

            await _rtspTransportClient.ConnectAsync(token);

            RtspRequestMessage  optionsRequest  = _requestMessageFactory.CreateOptionsRequest();
            RtspResponseMessage optionsResponse = await _rtspTransportClient.ExecuteRequest(optionsRequest, token);

            if (optionsResponse.StatusCode == RtspStatusCode.Ok)
            {
                ParsePublicHeader(optionsResponse.Headers[WellKnownHeaders.Public]);
            }

            RtspRequestMessage  describeRequest  = _requestMessageFactory.CreateDescribeRequest();
            RtspResponseMessage describeResponse =
                await _rtspTransportClient.EnsureExecuteRequest(describeRequest, token);

            string contentBaseHeader = describeResponse.Headers[WellKnownHeaders.ContentBase];

            if (!string.IsNullOrEmpty(contentBaseHeader))
            {
                _requestMessageFactory.ContentBase = new Uri(contentBaseHeader);
            }

            var parser = new SdpParser();
            IEnumerable <RtspTrackInfo> tracks = parser.Parse(describeResponse.ResponseBody);

            bool anyTrackRequested = false;

            foreach (RtspMediaTrackInfo track in GetTracksToSetup(tracks))
            {
                await SetupTrackAsync(initialTimeStamp, track, token);

                anyTrackRequested = true;
            }

            if (!anyTrackRequested)
            {
                throw new RtspClientException("Any suitable track is not found");
            }

            RtspRequestMessage  playRequest  = (initialTimeStamp != default(DateTime) ? _requestMessageFactory.CreatePlayRequest(initialTimeStamp) : _requestMessageFactory.CreatePlayRequest());
            RtspResponseMessage playResponse =
                await _rtspTransportClient.EnsureExecuteRequest(playRequest, token, 1);

            // TODO : Create a specific parse to convert the clock values
            Regex clockRegex = new Regex(@"clock=(?<startTime>\d{8}T\d{6}Z)\-(?<endTime>\d{8}T\d{6}Z)", RegexOptions.Singleline);

            foreach (string playResponseHeader in playResponse.Headers.GetValues("Range"))
            {
                Match clockMatches = clockRegex.Match(playResponseHeader);
                if (clockMatches.Success)
                {
                    _mediaPayloadParser.BaseTime = DateTime.ParseExact(clockMatches.Groups["startTime"].Value, "yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture, DateTimeStyles.None);
                }
            }
        }
        public RtspRequestMessage CreateTeardownRequest()
        {
            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.TEARDOWN, _rtspUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreateOptionsRequest()
        {
            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.OPTIONS, _rtspUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreateGetParameterRequest()
        {
            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.GET_PARAMETER, _rtspUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreateDescribeRequest()
        {
            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.DESCRIBE, _rtspUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Accept", "application/sdp");
            return(rtspRequestMessage);
        }
        private void AddAuthorizationHeader(RtspRequestMessage request)
        {
            Uri uri = ConnectionParameters.GetFixedRtspUri();

            string headerValue = _authenticator.GetResponse(request.CSeq, uri.ToString(),
                                                            request.Method.ToString(), Array.Empty <byte>());

            request.Headers.Add("Authorization", headerValue);
        }
        public RtspRequestMessage CreateSetupTcpInterleavedRequest(string trackName, int rtpChannel, int rtcpChannel)
        {
            Uri trackUri = GetTrackUri(trackName);

            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.SETUP, trackUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Transport", $"RTP/AVP/TCP;unicast;interleaved={rtpChannel}-{rtcpChannel}");
            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreateSetupUdpUnicastRequest(string trackName, int rtpPort, int rtcpPort)
        {
            Uri trackUri = GetTrackUri(trackName);

            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.SETUP, trackUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Transport", $"RTP/AVP/UDP;unicast;client_port={rtpPort}-{rtcpPort}");
            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreatePlayRequest()
        {
            Uri uri = GetContentBasedUri();

            var rtspRequestMessage =
                new RtspRequestMessage(RtspMethod.PLAY, uri, ProtocolVersion, NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Range", "npt=0.000-");
            return(rtspRequestMessage);
        }
Exemple #10
0
        public RtspRequestMessage CreateSetupUdpMulticastRequest(string trackName)
        {
            Uri trackUri = GetTrackUri(trackName);

            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.SETUP, trackUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Transport", $"RTP/AVP;multicast");
            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreateSetupUdpUnicastRequest(string trackName, int rtpPort, int rtcpPort)
        {
            Uri trackUri = !Uri.IsWellFormedUriString(trackName, UriKind.Absolute)
                ? new Uri(GetContentBasedUri(), trackName)
                : new Uri(trackName, UriKind.Absolute);

            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.SETUP, trackUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Transport", $"RTP/AVP/UDP;unicast;client_port={rtpPort}-{rtcpPort}");
            return(rtspRequestMessage);
        }
        public RtspRequestMessage CreateSetupTcpInterleavedRequest(string trackName, int rtpChannel, int rtcpChannel)
        {
            Uri trackUri = !Uri.IsWellFormedUriString(trackName, UriKind.Absolute)
                ? new Uri(GetContentBasedUri(), trackName)
                : new Uri(trackName, UriKind.Absolute);

            var rtspRequestMessage = new RtspRequestMessage(RtspMethod.SETUP, trackUri, ProtocolVersion,
                                                            NextCSeqProvider, _userAgent, SessionId);

            rtspRequestMessage.Headers.Add("Transport", $"RTP/AVP/TCP;unicast;interleaved={rtpChannel}-{rtcpChannel}");
            return(rtspRequestMessage);
        }
        public async Task <RtspResponseMessage> EnsureExecuteRequest(RtspRequestMessage requestMessage,
                                                                     CancellationToken token, int responseReadPortionSize = 0)
        {
            RtspResponseMessage responseMessage = await ExecuteRequest(requestMessage, token, responseReadPortionSize);

            if (responseMessage.StatusCode != RtspStatusCode.Ok)
            {
                throw new RtspBadResponseCodeException(responseMessage.StatusCode);
            }

            return(responseMessage);
        }
        private async Task SendRtspKeepAliveAsync(CancellationToken token)
        {
            RtspRequestMessage getParameterRequest = _requestMessageFactory.CreateGetParameterRequest();

            if (_connectionParameters.RtpTransport == RtpTransportProtocol.TCP)
            {
                await _rtspTransportClient.SendRequestAsync(getParameterRequest, token);
            }
            else
            {
                await _rtspTransportClient.EnsureExecuteRequest(getParameterRequest, token);
            }
        }
        private async Task CloseRtspSessionAsync(CancellationToken token)
        {
            RtspRequestMessage teardownRequest = _requestMessageFactory.CreateTeardownRequest();

            if (_connectionParameters.RtpTransport == RtpTransportProtocol.TCP)
            {
                await _rtspTransportClient.SendRequestAsync(teardownRequest, token);
            }
            else
            {
                await _rtspTransportClient.EnsureExecuteRequest(teardownRequest, token);
            }
        }
        public Task SendRequestAsync(RtspRequestMessage requestMessage, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (_authenticator != null)
            {
                AddAuthorizationHeader(requestMessage);
            }

            string requestMessageString = requestMessage.ToString();

            int written = Encoding.ASCII.GetBytes(requestMessageString, 0, requestMessageString.Length, _buffer, 0);

            return(WriteAsync(_buffer, 0, written));
        }
        public async Task ConnectAsync(CancellationToken token)
        {
            IRtspTransportClient rtspTransportClient = _transportClientProvider();

            Volatile.Write(ref _rtspTransportClient, rtspTransportClient);

            await _rtspTransportClient.ConnectAsync(token);

            RtspRequestMessage  optionsRequest  = _requestMessageFactory.CreateOptionsRequest();
            RtspResponseMessage optionsResponse = await _rtspTransportClient.ExecuteRequest(optionsRequest, token);

            if (optionsResponse.StatusCode == RtspStatusCode.Ok)
            {
                ParsePublicHeader(optionsResponse.Headers[WellKnownHeaders.Public]);
            }

            RtspRequestMessage  describeRequest  = _requestMessageFactory.CreateDescribeRequest();
            RtspResponseMessage describeResponse =
                await _rtspTransportClient.EnsureExecuteRequest(describeRequest, token);

            string contentBaseHeader = describeResponse.Headers[WellKnownHeaders.ContentBase];

            if (!string.IsNullOrEmpty(contentBaseHeader))
            {
                _requestMessageFactory.ContentBase = new Uri(contentBaseHeader);
            }

            var parser = new SdpParser();
            IEnumerable <RtspTrackInfo> tracks = parser.Parse(describeResponse.ResponseBody);

            bool anyTrackRequested = false;

            foreach (RtspMediaTrackInfo track in GetTracksToSetup(tracks))
            {
                await SetupTrackAsync(track, token);

                Codec             = track.Codec;
                anyTrackRequested = true;
            }

            if (!anyTrackRequested)
            {
                throw new RtspClientException("Any suitable track is not found");
            }

            RtspRequestMessage playRequest = _requestMessageFactory.CreatePlayRequest();
            await _rtspTransportClient.EnsureExecuteRequest(playRequest, token, 1);
        }
Exemple #18
0
        public RtspRequestMessage CreatePlayRequest(DateTime initialTimestamp)
        {
            Uri uri = GetContentBasedUri();

            var rtspRequestMessage =
                new RtspRequestMessage(RtspMethod.PLAY, uri, ProtocolVersion, NextCSeqProvider, _userAgent, SessionId);

            if (initialTimestamp.Kind == DateTimeKind.Utc)
            {
                rtspRequestMessage.Headers.Add("Range", $"clock={initialTimestamp.ToString("yyyyMMddThhmmssZ")}-");
            }
            else
            {
                rtspRequestMessage.Headers.Add("Range", $"clock={DateTime.SpecifyKind(initialTimestamp, DateTimeKind.Utc).ToString("yyyyMMddThhmmssZ")}-");
            }
            return(rtspRequestMessage);
        }
Exemple #19
0
        private async Task CloseRtspSessionAsync(CancellationToken token)
        {
            RtspRequestMessage teardownRequest = _requestMessageFactory.CreateTeardownRequest();

            if (_connectionParameters.RtpTransport == RtpTransportProtocol.TCP)
            {
                await _rtspTransportClient.SendRequestAsync(teardownRequest, token);
            }
            else if (_connectionParameters.RtpTransport == RtpTransportProtocol.MULTICAST)
            {
                // There is no need to leave multicast group because it is done automatically by OS when socket closes
                await _rtspTransportClient.EnsureExecuteRequest(teardownRequest, token);
            }
            else
            {
                await _rtspTransportClient.EnsureExecuteRequest(teardownRequest, token);
            }
        }
        public async Task <RtspResponseMessage> ExecuteRequest(RtspRequestMessage requestMessage,
                                                               CancellationToken token, int responseReadPortionSize = 0)
        {
            token.ThrowIfCancellationRequested();

            await SendRequestAsync(requestMessage, token);

            RtspResponseMessage responseMessage = await GetResponseAsync(responseReadPortionSize);

            if (responseMessage.StatusCode != RtspStatusCode.Unauthorized)
            {
                return(responseMessage);
            }

            if (ConnectionParameters.Credentials.IsEmpty() || _authenticator != null)
            {
                throw new RtspBadResponseCodeException(responseMessage.StatusCode);
            }

            string authenticateHeader = responseMessage.Headers[WellKnownHeaders.WwwAuthenticate];

            if (string.IsNullOrEmpty(authenticateHeader))
            {
                throw new RtspBadResponseCodeException(responseMessage.StatusCode);
            }

            _authenticator = Authenticator.Create(ConnectionParameters.Credentials, authenticateHeader);
            requestMessage.UpdateSequenceNumber();

            await SendRequestAsync(requestMessage, token);

            responseMessage = await GetResponseAsync();

            if (responseMessage.StatusCode == RtspStatusCode.Unauthorized)
            {
                throw new RtspBadResponseCodeException(responseMessage.StatusCode);
            }

            return(responseMessage);
        }