Exemplo n.º 1
0
        /// <summary>
        /// <see fref="https://tools.ietf.org/html/rfc2326#page-80">Use of SDP for RTSP Session Descriptions</see>
        /// In brief an the given <see cref="SessionDescription"/> must contain a <see cref="Sdp.Lines.ConnectionLine"/> in the <see cref="Sdp.MediaDescription"/>
        /// </summary>
        /// <param name="sdp"></param>
        /// <param name="controlUri"></param>
        /// <param name="baseUri"></param>
        /// <returns></returns>
        public static bool SupportsAggregateMediaControl(this SessionDescription sdp, out Uri controlUri, Uri baseUri = null)
        {
            controlUri = null;

            SessionDescriptionLine controlLine = sdp.ControlLine;

            //If there is a control line in the SDP it contains the URI used to setup and control the media
            if (controlLine == null)
            {
                return(false);
            }

            //Get the control token
            string controlPart = controlLine.Parts.Where(p => p.Contains(AttributeFields.Control)).FirstOrDefault();

            //If there is a controlPart in the controlLine
            if (false == string.IsNullOrWhiteSpace(controlPart))
            {
                /*
                 *  If this attribute contains only an asterisk (*), then the URL is
                 *  treated as if it were an empty embedded URL, and thus inherits the
                 *  entire base URL.
                 */
                controlPart = controlPart.Split(Media.Sdp.SessionDescription.ColonSplit, 2, StringSplitOptions.RemoveEmptyEntries).Last();

                //if unqualified then there is no aggregate control.
                if (controlPart == SessionDescription.WildcardString && baseUri == null)
                {
                    return(false);
                }

                //The control uri may be in the control part

                //Try to parse it
                if (Uri.TryCreate(controlPart, UriKind.RelativeOrAbsolute, out controlUri))
                {
                    //If parsing suceeded then the result is true only if the controlUri is absolute
                    if (controlUri.IsAbsoluteUri)
                    {
                        return(true);
                    }
                }

                //Try to create a uri relative to the base uri given
                if (Uri.TryCreate(baseUri, controlUri, out controlUri))
                {
                    //If the operation succeeded then the result is true.
                    return(true);
                }
            }

            //Another type of control line is present.
            return(false);
        }
 public bool Equals(SessionDescriptionLine other)
 {
     return(other.Encoding.Equals(m_Encoding)
            &&
            other.m_Type.Equals(m_Type)
            &&
            other.m_Seperator.Equals(m_Seperator)
            &&
            other.Length.Equals(Length)
            && //Calling ToString without taking account case
            ToString().Equals(other.ToString(), StringComparison.OrdinalIgnoreCase));
 }
        public static bool TryParse(string[] sdpLines, ref int index, out SessionDescriptionLine result)
        {
            try
            {
                result = Parse(sdpLines, ref index);

                return(result != null);
            }
            catch
            {
                result = null;

                return(false);
            }
        }
        /// <summary>
        /// Copies an existing instance
        /// </summary>
        /// <param name="other">The instance to copy.</param>
        public SessionDescriptionLine(SessionDescriptionLine other)
        {
            if (other == null)
            {
                throw new ArgumentNullException();
            }

            m_Encoding = other.m_Encoding;

            //Copies ValueType
            m_Type = other.m_Type;

            m_Seperator = other.m_Seperator;

            m_Parts = other.m_Parts;
        }
        public SessionDescriptionLine(SessionDescriptionLine other, bool reference = true, string seperator = null)
        {
            if (other == null)
            {
                throw new ArgumentNullException();
            }

            m_Encoding = other.m_Encoding;

            //Copies ValueType
            m_Type = other.m_Type;

            m_Seperator = seperator ?? other.m_Seperator;

            if (reference)
            {
                m_Parts = other.m_Parts;
            }
            else
            {
                m_Parts = new List <string>(other.m_Parts);
            }
        }
Exemplo n.º 6
0
    public void TestInitialObjectDescriptor()
    {
        Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);

        string testVector = @"v=0
o=- 1183588701 6 IN IP4 10.3.1.221
s=Elecard NWRenderer
i=Elecard streaming
u=http://www.elecard.com
[email protected]
c=IN IP4 239.255.0.1/64
b=CT:0
a=ISMA-compliance:2,2.0,2
a=mpeg4-iod: ""data:application/mpeg4-iod;base64,AoE8AA8BHgEBAQOBDAABQG5kYXRhOmFwcGxpY2F0aW9uL21wZWc0LW9kLWF1O2Jhc2U2NCxBVGdCR3dVZkF4Y0F5U1FBWlFRTklCRUFGM0FBQVBvQUFBRERVQVlCQkE9PQEbAp8DFQBlBQQNQBUAB9AAAD6AAAA+gAYBAwQNAQUAAMgAAAAAAAAAAAYJAQAAAAAAAAAAA2EAAkA+ZGF0YTphcHBsaWNhdGlvbi9tcGVnNC1iaWZzLWF1O2Jhc2U2NCx3QkFTZ1RBcUJYSmhCSWhRUlFVL0FBPT0EEgINAAAUAAAAAAAAAAAFAwAAQAYJAQAAAAAAAAAA""
m=video 10202 RTP/AVP 98
a=rtpmap:98 H264/90000
a=control:trackID=1
a=fmtp:98 packetization-mode=1; profile-level-id=4D001E; sprop-parameter-sets=Z00AHp5SAWh7IA==,aOuPIAAA
a=mpeg4-esid:201
m=audio 10302 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/48000/2
a=control:trackID=2
a=fmtp:96 streamtype=5; profile-level-id=255; mode=AAC-hbr; config=11900000000000000000; objectType=64; sizeLength=13; indexLength=3; indexDeltaLength=3
a=mpeg4-esid:101";

        Media.Sdp.SessionDescription sd = new Media.Sdp.SessionDescription(testVector);

        Console.WriteLine(sd.ToString());

        //Get the inital object descriptor line
        Media.Sdp.SessionDescriptionLine mpeg4IodLine = sd.Lines.Where(l => l.Type == 'a' && l.Parts.Any(p => p.Contains("mpeg4-iod"))).FirstOrDefault();

        System.Diagnostics.Debug.Assert(mpeg4IodLine != null, "Cannot find InitialObjectDescriptor Line");

        System.Diagnostics.Debug.Assert(mpeg4IodLine.Parts.Last() == "base64,AoE8AA8BHgEBAQOBDAABQG5kYXRhOmFwcGxpY2F0aW9uL21wZWc0LW9kLWF1O2Jhc2U2NCxBVGdCR3dVZkF4Y0F5U1FBWlFRTklCRUFGM0FBQVBvQUFBRERVQVlCQkE9PQEbAp8DFQBlBQQNQBUAB9AAAD6AAAA+gAYBAwQNAQUAAMgAAAAAAAAAAAYJAQAAAAAAAAAAA2EAAkA+ZGF0YTphcHBsaWNhdGlvbi9tcGVnNC1iaWZzLWF1O2Jhc2U2NCx3QkFTZ1RBcUJYSmhCSWhRUlFVL0FBPT0EEgINAAAUAAAAAAAAAAAFAwAAQAYJAQAAAAAAAAAA\"", "InitialObjectDescriptor Line Contents invalid.");
    }
        public override bool Equals(object obj)
        {
            if (System.Object.ReferenceEquals(this, obj))
            {
                return(true);
            }

            if (false == (obj is SessionDescriptionLine))
            {
                return(false);
            }

            SessionDescriptionLine other = obj as SessionDescriptionLine;

            return(other.Encoding == m_Encoding
                   &&
                   other.m_Type == m_Type
                   &&
                   other.m_Seperator == m_Seperator
                   &&
                   other.Length == Length
                   && //Calling ToString without taking account case
                   string.Compare(ToString(), other.ToString(), true) == 0);
        }
Exemplo n.º 8
0
        /// <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);
        }
Exemplo n.º 9
0
        /// <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);
        }
        public static SessionDescriptionLine Parse(params string[] lines) //index, count
        {
            int index = 0;

            return(SessionDescriptionLine.Parse(lines, ref index));
        }