private Uri DetermineRealUri() { // The VideoXpert system does some non-standard RTSP redirecting so that it can determine the intent of // the client (intent being live or playback). It stats off by creating a spoofed SDP and then will // redirect on play. What we will do it write a wrapper that does some of the RTSP calls to first // determine what the actual live RTSP uri is. using (RtspClient client = new RtspClient(_uri)) { try { var method = RtspRequest.RtspMethod.OPTIONS; CheckResponse(client.Send(RtspRequest.CreateBuilder() .Method(method) .Uri(_uri) .Build()), method); method = RtspRequest.RtspMethod.DESCRIBE; var res = CheckResponse(client.Send(RtspRequest.CreateBuilder() .Method(method) .Uri(_uri) .Build()), method); var sdp = res.GetBodyAsSdp(); if (!sdp.SessionName.Contains("Spoofed session")) { // We are not working with a spoofed session just return // the current uri. return(_uri); } Uri controlUri = null; var tracks = MediaTracks.FromSdp(sdp, _uri); foreach (var track in tracks) { if (track.Type.Is(MimeType.ANY_VIDEO)) { if (GetRedirectUri(client, track, out controlUri)) { return(controlUri); } } } throw new RtspClientException($"Unable to retrieve usable uri from server at endpoint '{_uri}'"); } catch (Exception e) { LOG.Error(e, $"Failed while communicating with RTSP server at '{_uri}'"); throw e; } } }
private bool GetRedirectUri(RtspClient client, MediaTrack track, out Uri uri) { var transport = TransportHeader.CreateBuilder() .Type(TransportType.RtspInterleaved) .InterleavedChannels(0, 1) .Build(); var method = RtspRequest.RtspMethod.SETUP; var res = CheckResponse(client.Send(RtspRequest.CreateBuilder() .Method(method) .Uri(track.ControlUri) .AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString()) .Build()), method); if (!res.Headers.ContainsKey(RtspHeaders.Names.SESSION)) { uri = null; return(false); } var rtspSession = Session.Parse(res.Headers[RtspHeaders.Names.SESSION]); method = RtspRequest.RtspMethod.PLAY; res = CheckResponse(client.Send(RtspRequest.CreateBuilder() .Method(method) .Uri(track.ControlUri) .AddHeader(RtspHeaders.Names.SESSION, rtspSession.ID) .Build()), method); var status = res.ResponseStatus; if (status.Is(RtspResponse.Status.MovedPermanently) || status.Is(RtspResponse.Status.MovedTemporarily)) { // We received a redirect lets get the uri and return it. if (res.Headers.ContainsKey(RtspHeaders.Names.LOCATION)) { var value = res.Headers[RtspHeaders.Names.LOCATION]; return(Uri.TryCreate(value, UriKind.RelativeOrAbsolute, out uri)); } } uri = null; return(false); }