What is Required for a Recorder Source for ArgusTv

User avatar
Kay Diefenthal
Posts: 226
Joined: Fri Nov 16, 2012 10:40 am
Location: Wachtberg, NRW, Germany
Contact:

What is Required for a Recorder Source for ArgusTv

Post by Kay Diefenthal » Sun Aug 04, 2013 10:11 am

i ask me what is required for deploy a Recorder Source

is it poosible to build a Recorder source that is sat>ip conform ? that mean there is a rtsp stack inside that sends the request to the sat>ip Server and give the Client the Responses

Exsample code for the sat>ip rtsp stack

Code: Select all

        private string _rtspServerName = Properties.Settings.Default.ServerName;
        private string _rtspServerIp= Properties.Settings.Default.ServerIpAddress;
        private string _rtspServerPort = Properties.Settings.Default.ServerPort;
        private Socket _rtspSocket;
        private int _rtspSequenceNum =0;
        private string _rtspResponse;
        private string _rtspSessionId;
        private int _rtspSessionTTL;
        private string _rtspStreamId;
        private string _clientRtpPort = Properties.Settings.Default.RtpPort;
        private string _clientRtcpPort = Properties.Settings.Default.RtcpPort;
        private string _serverRtpPort;
        private string _serverRtcpPort;
        private string _rtspStreamUrl;


        private bool Connect()
        {
            _rtspSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var ip = IPAddress.Parse(_rtspServerIp);
            var port = Convert.ToInt16(_rtspServerPort);
            var rtspEndpoint = new IPEndPoint(ip, port);
            _rtspSocket.Connect(rtspEndpoint);
            return  _rtspSocket.Connected;
        }
        private bool Disconnect()
        {
            var result = false;
            if (_rtspSocket != null && _rtspSocket.Connected)
            {
                _rtspSocket.Shutdown(SocketShutdown.Both);
                _rtspSocket.Close();
                result = false;
            }
            return result;
        }
        private bool Setup(string query)
        {
            var result = false;
            var sb = new StringBuilder();
            if (string.IsNullOrEmpty(_rtspSessionId))
            {
                sb.AppendFormat("{0} ", "SETUP");
                sb.AppendFormat("rtsp://{0}:{1}/?{2} RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort, query);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("Transport: RTP/AVP;{0};client_port={1}-{2}\r\n\r\n", "unicast", _clientRtpPort, _clientRtcpPort);
            }
            else
            {
                sb.AppendFormat("{0} ", "SETUP");
                sb.AppendFormat("rtsp://{0}:{1}/?{2} RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort, query);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("Session: {0}\r\n", _rtspSessionId);
                sb.AppendFormat("Transport: RTP/AVP;{0};client_port={1}-{2}\r\n\r\n", "unicast", _clientRtpPort, _clientRtcpPort);
            }
            result = SendRequest(sb.ToString());
            result = GetResponse();
            var lineArray = Regex.Split(_rtspResponse, @"[\r\n]+");
            foreach (var s in lineArray)
            {
                if (s.Contains("Session:"))
                {
                    var sessionline = s;
                    if (string.IsNullOrEmpty(sessionline))
                    {

                    }
                    var sessionlinevalues = sessionline.Split(';');
                    var sessionvalues = sessionlinevalues[0].Split(':');
                    _rtspSessionId = sessionvalues[1];

                    var ttlvalues = sessionlinevalues[1].Split('=');
                    _rtspSessionTTL = int.Parse(ttlvalues[1]);
                }
                if (s.Contains("Transport:"))
                {
                    var transportline = s;
                    if (string.IsNullOrEmpty(transportline))
                    {

                    }
                    var transportvalues = transportline.Split(';');
                    foreach (var transportvalue in transportvalues)
                    {
                        if (transportvalue.Contains("server_port"))
                        {
                            var serverportvalues = transportvalue.Substring(("server_port").Length)
                                                                 .Trim()
                                                                 .Split('=');
                            
                               var ports = serverportvalues[1].Split('-');
                            _serverRtpPort = ports[0];
                            _serverRtcpPort = ports[1];
                        }
                    }
                }
                if (s.Contains("com.ses.streamID:"))
                {
                    _rtspStreamId = s.Substring(("com.ses.streamID:").Length).Trim();
                }
            }
            
            return result;
        }
        private bool Play(string query)
        {
            var result = false;
            var sb = new StringBuilder();
            if (string.IsNullOrEmpty(query))
            {
                sb.AppendFormat("{0} ", "PLAY");
                sb.AppendFormat("rtsp://{0}:{1}/stream={2} RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort,
                                _rtspStreamId);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("User-Agent: LibVLC/2.0.7 (Live555 Streaming Media v2012.12.18\r\n");
                sb.AppendFormat("Session: {0}\r\n\r\n", _rtspSessionId);
                
            }
            else
            {
                sb.AppendFormat("{0} ", "PLAY");
                sb.AppendFormat("rtsp://{0}:{1}/stream={2}?{3} RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort,
                                _rtspStreamId, query);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("User-Agent: LibVLC/2.0.7 (Live555 Streaming Media v2012.12.18\r\n");
                sb.AppendFormat("Session: {0}\r\n\r\n", _rtspSessionId);
            }
            result =SendRequest(sb.ToString());
            result = GetResponse();
            var lineArray = Regex.Split(_rtspResponse, @"[\r\n]+");
            foreach (var s in lineArray)
            {
                if (s.Contains("Session:"))
                {
                    var sessionline = s;
                    if (string.IsNullOrEmpty(sessionline))
                    {

                    }
                    var sessionvalues = sessionline.Split(':');
                    _rtspSessionId = sessionvalues[1];

                }
                if (s.Contains("RTP-Info:"))
                {
                    var rtpinfoline = s;
                    if (string.IsNullOrEmpty(rtpinfoline))
                    {

                    }
                    
                    var rtpinfovalues = rtpinfoline.Split(' ');
                    _rtspStreamUrl = rtpinfovalues[1].Replace("url=", "");
                }
            }
           
            Describe();
            MediaCenterEnvironment.PlayMedia(MediaType.Video, "rtp://192.168.2.100:52010", false);
                
            return result;
        }
        private bool Options()
        {
            var result = false;
            var sb = new StringBuilder();
            if (string.IsNullOrEmpty(_rtspSessionId))
            {
                sb.AppendFormat("{0} ", "OPTIONS");
                sb.AppendFormat("rtsp://{0}:{1}/ RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort);
                sb.AppendFormat("CSeq: {0}\r\n\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
            }
            else
            {
                sb.AppendFormat("{0} ", "OPTIONS");
                sb.AppendFormat("rtsp://{0}:{1}/ RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("Session: {0}\r\n\r\n", _rtspSessionId);
            }
            result =SendRequest(sb.ToString());
            result=GetResponse();
            return result;
        }
        private bool Describe()
        {
            var result = false;
            var sb = new StringBuilder();
            if (string.IsNullOrEmpty(_rtspSessionId))
            {
                sb.AppendFormat("{0} ", "DESCRIBE");
                sb.AppendFormat("rtsp://{0}:{1}/ RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("Accept: application/sdp\r\n\r\n");
            }
            else
            {
                sb.AppendFormat("{0} ", "DESCRIBE");
                sb.AppendFormat("rtsp://{0}:{1}/ RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort);
                sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
                sb.AppendFormat("Session: {0}\r\n", _rtspSessionId);
                sb.AppendFormat("Accept: application/sdp\r\n\r\n");
            }
            result = SendRequest(sb.ToString());
            result = GetResponse();
            var lineArray = Regex.Split(_rtspResponse, @"[\r\n]+");
            foreach (var s in lineArray)
            {
                if (s.Contains("v="))
                {
                    
                }
                if (s.Contains("o="))
                {

                }
                if (s.Contains("s="))
                {

                }
                if (s.Contains("t="))
                {

                }
                if (s.Contains("m="))
                {

                }
                if (s.Contains("c="))
                {

                }
                if (s.Contains("a="))
                {

                }
               
            }

            return result;
        }
        private bool TearDown()
        {
            var result = false;
            var sb = new StringBuilder();
            sb.AppendFormat("{0} ", "TEARDOWN");
            sb.AppendFormat("rtsp://{0}:{1}/stream={2} RTSP/1.0\r\n", _rtspServerIp, _rtspServerPort, _rtspStreamId);
            sb.AppendFormat("CSeq: {0}\r\n", (++_rtspSequenceNum).ToString(CultureInfo.InvariantCulture));
            sb.AppendFormat("Session: {0}\r\n\r\n", _rtspSessionId);
            result = SendRequest(sb.ToString());
            return result;
        }
        private bool SendRequest(string request)
        {
            var result = false;
            if (_rtspSocket == null)
            {
                
            }
            try
            {
                var sendBuffer = Utils.StringToBytes(request);
                var sendBytesCount = _rtspSocket.Send(sendBuffer, sendBuffer.Length, SocketFlags.None);
                if (sendBytesCount < 1)
                {
                    result = false;
                }

                result = true;
            }
            catch (Exception e)
            {
                result = false;
            }
            return result;

        }
        private bool GetResponse()
        {
            var result = false;
            var revBytesCount = 0;
            var revBuffer = new byte[1024 * 4];
            _rtspResponse = string.Empty;
            _rtspSocket.ReceiveTimeout = 5000;
            while (true)
            {
                try
                {
                    revBytesCount = _rtspSocket.Receive(revBuffer, revBuffer.Length, SocketFlags.None);
                    if (revBytesCount >= 1)
                    {
                        break;
                    }
                    if (_rtspSocket.ReceiveTimeout >= 5000)
                    {
                        break;
                    }
                }
                catch (SocketException )
                {
                    
                }
            }
            if (revBytesCount >= 1)
            {

                _rtspResponse = Utils.BytesToString(revBuffer, revBytesCount);
                if (_rtspResponse.StartsWith("RTSP/1.0"))
                {
                    var dstArray = _rtspResponse.Split(' ');
                    if (dstArray.Length > 1)
                    {
                        var code = dstArray[1];
                        if (code.Equals("200"))
                        {
                            result = true;
                        }
                    }
                }
            }
            
            return result;
        }

        public void Close()
        {
            TearDown();
            Disconnect();
        }


User avatar
dot-i
Site Admin
Posts: 5848
Joined: Mon Oct 01, 2012 3:40 pm

Re: What is Required for a Recorder Source for ArgusTv

Post by dot-i » Sun Aug 04, 2013 12:04 pm

The api for a recorder is best demonstrated by the source code of the MP TV Server recorder as found on the ARGUS TV GitHub page.

Basically it needs the ability to "allocate" a scheduled recording to a source (card) and the ability to actually perform this recording to a given unc path.
I have the heart of a child. I keep it in a jar on my shelf. -- Robert Bloch
Image

User avatar
Kay Diefenthal
Posts: 226
Joined: Fri Nov 16, 2012 10:40 am
Location: Wachtberg, NRW, Germany
Contact:

Re: What is Required for a Recorder Source for ArgusTv

Post by Kay Diefenthal » Sun Aug 04, 2013 12:55 pm

hi Dot-I

i Know that you share this but the base question is, is it possible

the channelscan and Play runs over the rtsp see the wireshark screenshoots
Channelscan rtsp.PNG
Channelscan rtsp.PNG (272.78 KiB) Viewed 20458 times
channelscan rtp Packets.PNG
channelscan rtp Packets.PNG (115.55 KiB) Viewed 20458 times
this rtsp commands and rtp Response are the question can i use this with the Recorder methods ?

User avatar
dot-i
Site Admin
Posts: 5848
Joined: Mon Oct 01, 2012 3:40 pm

Re: What is Required for a Recorder Source for ArgusTv

Post by dot-i » Sun Aug 04, 2013 4:41 pm

Let me put it like this, if you can write a simple command line utility to create a .ts file out of this, that would be a great start to develop it into a full fledged recorder.
I have the heart of a child. I keep it in a jar on my shelf. -- Robert Bloch
Image

User avatar
Kay Diefenthal
Posts: 226
Joined: Fri Nov 16, 2012 10:40 am
Location: Wachtberg, NRW, Germany
Contact:

Re: What is Required for a Recorder Source for ArgusTv

Post by Kay Diefenthal » Sun Aug 04, 2013 5:54 pm

dot-i wrote:Let me put it like this, if you can write a simple command line utility to create a .ts file out of this, that would be a great start to develop it into a full fledged recorder.

i can write a tool that you allow become a stream with rtp packets
the other is if you want see it in Action can you look on my System with teamviewer

i have two sat>Ip Server Digital Devices OctopusNet and the Telestar Digibit R1 for debuging here

User avatar
dot-i
Site Admin
Posts: 5848
Joined: Mon Oct 01, 2012 3:40 pm

Re: What is Required for a Recorder Source for ArgusTv

Post by dot-i » Tue Aug 06, 2013 5:36 pm

Does such a captured file play in MediaPortal, XBMC and vlc?
I have the heart of a child. I keep it in a jar on my shelf. -- Robert Bloch
Image

User avatar
Kay Diefenthal
Posts: 226
Joined: Fri Nov 16, 2012 10:40 am
Location: Wachtberg, NRW, Germany
Contact:

Re: What is Required for a Recorder Source for ArgusTv

Post by Kay Diefenthal » Tue Aug 06, 2013 6:33 pm

dot-i wrote:Does such a captured file play in MediaPortal, XBMC and vlc?
yes vlc and wmp12(if Lav directshow is installed)

User avatar
Kay Diefenthal
Posts: 226
Joined: Fri Nov 16, 2012 10:40 am
Location: Wachtberg, NRW, Germany
Contact:

Re: What is Required for a Recorder Source for ArgusTv

Post by Kay Diefenthal » Tue Aug 06, 2013 9:20 pm

Kay Diefenthal wrote:
dot-i wrote:Does such a captured file play in MediaPortal, XBMC and vlc?
yes vlc and wmp12(if Lav directshow is installed)
here is the test iknow there is something to do
but the Basis (rtsp ) works
Sat2Ip Discovery Sample.PNG
Sat2Ip Discovery Sample.PNG (76.8 KiB) Viewed 20411 times
Sat2Ip Rtsp Sample.PNG
Sat2Ip Rtsp Sample.PNG (177.45 KiB) Viewed 20411 times
Attachments
Sat2Ip Source + Binaries.zip
(434.56 KiB) Downloaded 706 times

User avatar
dot-i
Site Admin
Posts: 5848
Joined: Mon Oct 01, 2012 3:40 pm

Re: What is Required for a Recorder Source for ArgusTv

Post by dot-i » Tue Aug 06, 2013 9:55 pm

Kay Diefenthal wrote:
dot-i wrote:Does such a captured file play in MediaPortal, XBMC and vlc?
yes vlc and wmp12(if Lav directshow is installed)
Ok, cool, and what about XBMC? If that plays it too, this could serve directly as a recording file.
I have the heart of a child. I keep it in a jar on my shelf. -- Robert Bloch
Image

User avatar
luetty
Posts: 535
Joined: Wed Nov 19, 2008 2:10 pm
Location: Germany/ Westerwald

Re: What is Required for a Recorder Source for ArgusTv

Post by luetty » Wed Aug 07, 2013 1:39 am

very cooool Kay! :D

i'm interested, using OctopusNet, too.
Please go forward......

ciao
luetty
Image

Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests