/// <summary> /// Parses the <see cref="MediaDescription.ControlLine"/> and if present /// </summary> /// <param name="mediaDescription"></param> /// <param name="source"></param> /// <returns></returns> public static Uri GetAbsoluteControlUri(this MediaDescription mediaDescription, Uri source, SessionDescription sessionDescription = null) { if (source == null) { throw new ArgumentNullException("source"); } if (mediaDescription == null) { return(source); } if (false == source.IsAbsoluteUri) { throw new InvalidOperationException("source.IsAbsoluteUri must be true."); } SessionDescriptionLine controlLine = mediaDescription.ControlLine; //If there is a control line in the SDP it contains the URI used to setup and control the media if (controlLine != null) { //Todo, make typed line for controlLine // GC: Rewrote this somewhat because it was destroying valid absolute URL provided by AXIS media server in the MediaDescription Control field. // This make break media servers which use a relative path. TODO: Test with other servers. string controlPart = ""; if (controlLine.Parts.Count() > 2) { foreach (string part in controlLine.Parts) { if (part == "control") { } else if (part == "rtsp") { controlPart += part + ":"; } else { controlPart += part; } } } else { controlPart = controlLine.Parts.Last(); } //If there is a controlPart in the controlLine if (false == string.IsNullOrWhiteSpace(controlPart)) { //Prepare the part // GC: Commented this out because it was destroying valid absolute URL provided by AXIS media server in the MediaDescription Control field. // This make break media servers which use a relative path. TODO: Test with other servers. //controlPart = controlPart.Split(Media.Sdp.SessionDescription.ColonSplit, 2, StringSplitOptions.RemoveEmptyEntries).Last(); //Create a uri Uri controlUri = new Uri(controlPart, UriKind.RelativeOrAbsolute); //Determine if its a Absolute Uri if (controlUri.IsAbsoluteUri) { return(controlUri); } //Return a new uri using the original string and the controlUri relative path. //Hopefully the direction of the braces matched.. //string.Join(source.OriginalString, controlUri.OriginalString); return(new Uri(source.OriginalString.EndsWith(SessionDescription.ForwardSlashString) ? source.OriginalString + controlUri.OriginalString : string.Join(SessionDescription.ForwardSlashString, source.OriginalString, controlUri.OriginalString))); //Todo, ensure that any parameters have also been restored... #region Explination //I wonder if Mr./(Dr) Fielding is happy... //Let source = //rtsp://alt1.v7.cache3.c.youtube.com/CigLENy73wIaHwmddh2T-s8niRMYDSANFEgGUgx1c2VyX3VwbG9hZHMM/0/0/0/1/video.3gp/trackID=0 //Call //return new Uri(source, controlUri); //Result = //rtsp://alt1.v7.cache3.c.youtube.com/CigLENy73wIaHwmddh2T-s8niRMYDSANFEgGUgx1c2VyX3VwbG9hZHMM/0/0/0/1/trackID=0 //Useless when the source doesn't end with '/', e.g. same problem with Uri constructor. //System.UriBuilder builder = new UriBuilder(source); //builder.Path += controlUri.ToString(); //"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov/trackID=1" #endregion } } //Try to take the session level control uri Uri sessionControlUri; //If there was a session description given and it supports aggregate media control then return that uri if (sessionDescription != null && sessionDescription.SupportsAggregateMediaControl(out sessionControlUri, source)) { return(sessionControlUri); } //There is no control line, just return the source. return(source); }
/// <summary> /// Parses the <see cref="MediaDescription.ControlLine"/> and if present /// </summary> /// <param name="mediaDescription"></param> /// <param name="source"></param> /// <returns></returns> public static Uri GetAbsoluteControlUri(this MediaDescription mediaDescription, Uri source, SessionDescription sessionDescription = null) { if (object.ReferenceEquals(source, null)) { throw new ArgumentNullException("source"); } if (Common.IDisposedExtensions.IsNullOrDisposed(mediaDescription)) { return(source); } if (source.IsAbsoluteUri.Equals(false)) { throw new InvalidOperationException("source.IsAbsoluteUri must be true."); } SessionDescriptionLine controlLine = mediaDescription.ControlLine; //If there is a control line in the SDP it contains the URI used to setup and control the media if (object.ReferenceEquals(controlLine, null).Equals(false)) { //Todo, make typed line for controlLine string controlPart = controlLine.Parts.Last(); //controlLine.Parts.Where(p => p.StartsWith(AttributeFields.Control)).FirstOrDefault(); //If there is a controlPart in the controlLine if (string.IsNullOrWhiteSpace(controlPart).Equals(false)) { //Prepare the part controlPart = controlPart.Split(Media.Sdp.SessionDescription.ColonSplit, 2, StringSplitOptions.RemoveEmptyEntries).Last(); //Create a uri Uri controlUri = new Uri(controlPart, UriKind.RelativeOrAbsolute); //Determine if its a Absolute Uri if (controlUri.IsAbsoluteUri) { return(controlUri); } //Return a new uri using the original string and the controlUri relative path. //Hopefully the direction of the braces matched.. //string.Join(source.OriginalString, controlUri.OriginalString); return(new Uri(source.OriginalString.EndsWith(SessionDescription.ForwardSlashString) ? source.OriginalString + controlUri.OriginalString : string.Join(SessionDescription.ForwardSlashString, source.OriginalString, controlUri.OriginalString))); //Todo, ensure that any parameters have also been restored... #region Explination //I wonder if Mr./(Dr) Fielding is happy... //Let source = //rtsp://alt1.v7.cache3.c.youtube.com/CigLENy73wIaHwmddh2T-s8niRMYDSANFEgGUgx1c2VyX3VwbG9hZHMM/0/0/0/1/video.3gp/trackID=0 //Call //return new Uri(source, controlUri); //Result = //rtsp://alt1.v7.cache3.c.youtube.com/CigLENy73wIaHwmddh2T-s8niRMYDSANFEgGUgx1c2VyX3VwbG9hZHMM/0/0/0/1/trackID=0 //Useless when the source doesn't end with '/', e.g. same problem with Uri constructor. //System.UriBuilder builder = new UriBuilder(source); //builder.Path += controlUri.ToString(); //"rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov/trackID=1" #endregion } } //Try to take the session level control uri Uri sessionControlUri; //If there was a session description given and it supports aggregate media control then return that uri if (Common.IDisposedExtensions.IsNullOrDisposed(sessionDescription).Equals(false) && sessionDescription.SupportsAggregateMediaControl(out sessionControlUri, source)) { return(sessionControlUri); } //There is no control line, just return the source. return(source); }