2

I'm writing a RTSP client module and for this, I need to parse an very variable URI. But I'm completely stuck about which method I should use (most-failsafe) and how to accomplish this.

An example URI could look like this:

rtsp://192.168.1.100:554/videocam/media/1/video/1
\_/    \_______________/\_______/\______________/
 |              |           |           |
scheme      authority     [sub]     [mediacontrol]

But also other possibilities:

192.168.1.100/videocam/media/1/video/1
192.168.1.100:6000/media/1/video/1
192.168.1.100:6000/videocam

I need the following information:

IP         | how can I recognise this pattern [num].[num].[num].[num]?
Port       | easy if the string contains rtsp://, but what about just a number? 1-65555
Sub        | Optional subpath, can completely vary!
MediaLevel | Optional MediaLevel (indicator for stream/track), 
             not to be confused with the path. MediaLevel can be also just like this: track1 or m1s3 or media1/video1.. see?
             I can't go for the slash, also the path also can contain multiple slashes

Maybe there's a library for such tasks?

Thank you.

6
  • cant you divide it along the '/' and then count . e.g the second last one on the left must always be autority etc..? Commented Aug 20, 2012 at 11:46
  • So your second example has no "sub" and the third no "mediacontrol"? Is mediacontrol always a "list" of /string/int/ pairs? Also, can a sub contain numbers and must a mediacontrol start with a character? Commented Aug 20, 2012 at 11:48
  • I'd love to help, but there needs to be some way to differentiate a 'mediacontrol'/'medialevel' from a 'sub'... what if you have no mediacontrol, but the sub is media/3/video/4 or what if there is a sub like that with a mediacontrol, like media/1/video/4/media/3/video/123??? Commented Aug 20, 2012 at 12:41
  • @CodeJockey there IS actually a mediacontrol - it is returned by most devices via the SDP string, but sometimes in a very strange way: some devices return a perfect to use string e.g media/1/video/2/ or track1video2, but others return things like "m1;v2" or the full absolute path incl. sub path. So I don't think that's reliable. Host/Port solved, thanks to the heroic functionallity of URI class and the hint from L.B (it's so damn trivial..), but I'm still stuck in separating the path from the mediacontrol. Another camera I have brought up a new case which is.. pretty confusing: Commented Aug 20, 2012 at 14:26
  • rtsp://192.168.1.117:554/stream1_channel1 I thought this was obviously a mediacontrol, but due to the fact that the camera has only 1 stream on 1 channel and after analysing the SDP string, it's a subpath (the mediacontrol in this case - which was nowhere documented is "vidshow1"..) Ridiculous! Commented Aug 20, 2012 at 14:31

3 Answers 3

3
var uri = new Uri("rtsp://192.168.1.100:554/videocam/media/1/video/1");
var host = uri.Host;
var port = uri.Port;
var sub = uri.Segments[1];
var mlevel = uri.Segments.Skip(2).ToArray();
Sign up to request clarification or add additional context in comments.

3 Comments

I understand, but it seems like those checks make up the interesting part of this question.
I believe this to be the correct answer given the simple example presented. If there are more complicated exceptions that need to be accounted they should be presented as well.
@Menefee upon critical examination, you may notice one of the URLs in the example is of the form IP:Port/MediaLevel (no 'sub'), so while I would say there is room for improvement in the question, this really isn't a completely correct answer
0

Here is a quick example of how to use the UriBuilder class. It is a bit verbose because it is an example and is not ready for production. If more subs are to be identified then they can be added to the Sub List as shown in the example.

class Program
    {
        private static string _scheme = string.Empty;
        private static string _host = string.Empty;
        private static string _sub = string.Empty;

        static void Main(string[] args)
        {
            ParseUri("rtsp://192.168.1.100:554/videocam/media/1/video/1");
            ParseUri("192.168.1.100/videocam/media/1/video/1");
            ParseUri("192.168.1.100:6000/media/1/video/1");
            ParseUri("192.168.1.100:6000/videocam");
            // example of adding a new sub
            Sub.Add("sample");
            ParseUri("192.168.1.100:6000/sample/");
            Console.ReadLine();
        }

        private static void ParseUri(string URI)
        {
            UriBuilder uri = new UriBuilder(URI);
            _scheme = uri.Scheme;
            _host = uri.Host;
            _sub = string.Empty;
            StringBuilder sb = new StringBuilder();
            foreach (string s in uri.Uri.Segments)
            {
                if (Sub.Contains(s.Replace("/","")))
                {_sub = s;}
                else
                { sb.Append(s); }
            }

            Console.Out.WriteLine("+++++++++++++");
            Console.Out.WriteLine("URI: {0}",URI);
            Console.Out.WriteLine("Scheme: {0}", _scheme);
            Console.Out.WriteLine("sub: {0}",_sub);
            Console.Out.WriteLine("mediaControl: {0}", sb.ToString());
        }

        private static List<string> Sub
        {
            get
            {
                List<string> sub = new List<string>();
                sub.Add("videocam");
                return sub;
            }
        }
    }

Comments

0
                trace("Url      : {0}", turl.Text);
                var uri = new Uri(turl.Text);
                string host = uri.Host;
                int port = uri.Port;
                string userInfo = uri.UserInfo;
                string subStream = "";
                string userName = "";
                string password = "";
                if (uri.Segments?.Any() == true)
                {
                    subStream = string.Join("", uri.Segments);
                }
                if (!string.IsNullOrEmpty(userInfo))
                {
                    if (userInfo.Contains(":"))
                    {
                        string[] data = userInfo.Split(':');
                        userName = data[0];
                        password = data[1];
                    }
                    else
                    {
                        userName = userInfo;

                    }
                }
                trace("host     : {0}", host);
                trace("port     : {0}", port);
                trace("userName : {0}", userName);
                trace("password : {0}", password);
                trace("subStream: {0}", subStream);

Without user info enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.