public void sourceRequest(ISourceRequestResult aISourceRequestResult) { if (aISourceRequestResult == null) { return; } mLockWrite.Set(); if (mISourceRequestResult == null) { mISourceRequestResult = aISourceRequestResult; if (m_client != null) { m_client.Connect(mURL, RTSPClient.RTP_TRANSPORT.TCP); } } }
public void Connect() { byte [] rbs = new byte[ 4 + 8 + 16 ]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes( rbs ); string sid = String.Format( "{0:D10}", BitConverter.ToUInt32( rbs, 0 ) ); string sci = String.Format( "{0:X16}", BitConverter.ToUInt64( rbs, 4 ) ); string sac = Convert.ToBase64String( rbs, 12, 16 ); string url = String.Format( "rtsp://{0}/{1}", local, sid ); rc = new RTSPClient( host, 5000, url ); rc.UserAgent = "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)"; rc.AddHeaders.Set( "Client-Instance", sci ); rc.Connect(); string key = Convert.ToBase64String( RSAEncrypt( alg.Key ) ); string iv = Convert.ToBase64String( alg.IV ); string sdp = String.Format( "v=0\r\n" + "o=iTunes {0} 0 IN IP4 {1}\r\n" + "s=iTunes\r\n" + "c=IN IP4 {2}\r\n" + "t=0 0\r\n" + "m=audio 0 RTP/AVP 96\r\n" + "a=rtpmap:96 AppleLossless\r\n" + "a=fmtp:96 4096 0 16 40 10 14 2 255 0 0 44100\r\n" + "a=rsaaeskey:{3}\r\n" + "a=aesiv:{4}\r\n", sid, local, host, key.Replace( "=", "" ), iv.Replace( "=", "" ) ); rc.AddHeaders.Set( "Apple-Challenge", sac.Replace( "=", "" ) ); rc.AnnounceSDP( sdp ); rc.AddHeaders.Remove( "Apple-Challenge" ); Hashtable ht = rc.Setup(); string aj = (string)ht[ "Audio-Jack-Status" ]; if( aj == null ) throw new Exception( "Audio-Jack-Status is missing" ); string [] ptokens = aj.Split( new char[] { ';' } ); for( int i = 0; i < ptokens.Length; i++ ) { string [] ctokens = ptokens[ i ].Split( new char[] { '=' } ); for( int j = 0; j < ctokens.Length; j++ ) { if( ctokens.Length == 1 && ctokens[ 0 ].Trim().Equals( "connected" ) ) { ajstatus = JACK_STATUS_CONNECTED; } else if( ctokens.Length == 2 && ctokens[ 0 ].Trim().Equals( "type" ) ) { if( ctokens[ 1 ].Trim().Equals( "digital" ) ) ajtype = JACK_TYPE_DIGITAL; } } } rc.Record(); UpdateVolume(); tcdata = new TcpClient(); tcdata.Connect( host, rc.ServerPort ); nsdata = tcdata.GetStream(); }
public async void rtspClientStart() { rtspCancel = new CancellationTokenSource(); var url = "rtsp://192.168.0.10:8554/H264Video"; String now = DateTime.Now.ToString("yyyyMMdd_HHmmss"); MemoryStream fs_vps = null; // used to write the video MemoryStream fs_v = null; // used to write the video MemoryStream fs_a = null; // used to write the audio h264 = false; h265 = false; bool spsdone = false; RTSPClient c = new RTSPClient(); // The SPS/PPS comes from the SDP data // or it is the first SPS/PPS from the H264 video stream c.Received_SPS_PPS += (byte[] sps, byte[] pps) => { h264 = true; if (fs_vps == null) { String filename = "rtsp_capture_" + now + ".264"; fs_vps = new MemoryStream(); } if (fs_vps != null) { fs_vps.SetLength(0); fs_vps.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4); // Write Start Code fs_vps.Write(sps, 0, sps.Length); fs_vps.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4); // Write Start Code fs_vps.Write(pps, 0, pps.Length); } }; c.Received_VPS_SPS_PPS += (byte[] vps, byte[] sps, byte[] pps) => { h265 = true; if (fs_vps == null) { String filename = "rtsp_capture_" + now + ".265"; fs_vps = new MemoryStream(); } if (fs_vps != null) { fs_vps.SetLength(0); fs_vps.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4); // Write Start Code fs_vps.Write(vps, 0, vps.Length); // Video parameter set fs_vps.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4); // Write Start Code fs_vps.Write(sps, 0, sps.Length); // Sequence Parameter Set fs_vps.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4); // Write Start Code fs_vps.Write(pps, 0, pps.Length); // Picture Parameter Set } }; // Video NALs. May also include the SPS and PPS in-band for H264 c.Received_NALs += (List <byte[]> nal_units) => { foreach (byte[] nal_unit in nal_units) { // Output some H264 stream information if (h264 && nal_unit.Length > 0) { int nal_ref_idc = (nal_unit[0] >> 5) & 0x03; int nal_unit_type = nal_unit[0] & 0x1F; String description = ""; if (nal_unit_type == 1) { description = "NON IDR NAL"; } else if (nal_unit_type == 5) { description = "IDR NAL"; } else if (nal_unit_type == 6) { description = "SEI NAL"; } else if (nal_unit_type == 7) { description = "SPS NAL"; } else if (nal_unit_type == 8) { description = "PPS NAL"; } else if (nal_unit_type == 9) { description = "ACCESS UNIT DELIMITER NAL"; } else { description = "OTHER NAL"; } //Console.WriteLine("NAL Ref = " + nal_ref_idc + " NAL Type = " + nal_unit_type + " " + description); } // Output some H265 stream information if (h265 && nal_unit.Length > 0) { int nal_unit_type = (nal_unit[0] >> 1) & 0x3F; String description = ""; if (nal_unit_type == 1) { description = "NON IDR NAL"; } else if (nal_unit_type == 19) { description = "IDR NAL"; } else if (nal_unit_type == 32) { description = "VPS NAL"; } else if (nal_unit_type == 33) { description = "SPS NAL"; } else if (nal_unit_type == 34) { description = "PPS NAL"; } else if (nal_unit_type == 39) { description = "SEI NAL"; } else { description = "OTHER NAL"; } //Console.WriteLine("NAL Type = " + nal_unit_type + " " + description); } // we need sps... first if (!h264 && !h265) { return; } if (!spsdone) { if (callbacks == null || callbacks.buffers.Count == 0) { return; } var index = callbacks.buffers.Pop(); var buffer = codec.GetInputBuffer(index); buffer.Clear(); buffer.Put(fs_vps.ToArray()); codec.QueueInputBuffer(index, 0, (int)fs_vps.Length, 0, MediaCodecBufferFlags.CodecConfig); spsdone = true; fs_v = new MemoryStream(); } if (fs_v != null) { fs_v.Write(new byte[] { 0x00, 0x00, 0x00, 0x01 }, 0, 4); // Write Start Code fs_v.Write(nal_unit, 0, nal_unit.Length); // Write NAL } if (callbacks == null || fs_v == null || callbacks.buffers.Count == 0) { return; } try { var index = callbacks.buffers.Pop(); var buffer = codec.GetInputBuffer(index); buffer.Clear(); buffer.Put(fs_v.ToArray()); codec.QueueInputBuffer(index, 0, (int)fs_v.Length, 0, MediaCodecBufferFlags.None); fs_v.SetLength(0); } catch { } } }; // seperate and stay running Task.Run(() => { while (rtspCancel != null && true) { try { if (rtspCancel.Token.IsCancellationRequested) { return; } c.Connect(url, RTSPClient.RTP_TRANSPORT.UDP); var lastrtp = 0; int cnt = 0; while (!c.StreamingFinished()) { rtsprunning = true; Thread.Sleep(500); // existing if (rtspCancel.Token.IsCancellationRequested) { c.Stop(); return; } // no rtp in .5 sec if (lastrtp == c.rtp_count && cnt++ > 5) { c.Stop(); rtspCancel = null; return; } lastrtp = c.rtp_count; } rtsprunning = false; } catch { } } }); }
public void Connect() { byte [] rbs = new byte[4 + 8 + 16]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes(rbs); string sid = String.Format("{0:D10}", BitConverter.ToUInt32(rbs, 0)); string sci = String.Format("{0:X16}", BitConverter.ToUInt64(rbs, 4)); string sac = Convert.ToBase64String(rbs, 12, 16); string url = String.Format("rtsp://{0}/{1}", local, sid); rc = new RTSPClient(host, 5000, url); rc.UserAgent = "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)"; rc.AddHeaders.Set("Client-Instance", sci); rc.Connect(); string key = Convert.ToBase64String(RSAEncrypt(alg.Key)); string iv = Convert.ToBase64String(alg.IV); string sdp = String.Format( "v=0\r\n" + "o=iTunes {0} 0 IN IP4 {1}\r\n" + "s=iTunes\r\n" + "c=IN IP4 {2}\r\n" + "t=0 0\r\n" + "m=audio 0 RTP/AVP 96\r\n" + "a=rtpmap:96 AppleLossless\r\n" + "a=fmtp:96 4096 0 16 40 10 14 2 255 0 0 44100\r\n" + "a=rsaaeskey:{3}\r\n" + "a=aesiv:{4}\r\n", sid, local, host, key.Replace("=", ""), iv.Replace("=", "")); rc.AddHeaders.Set("Apple-Challenge", sac.Replace("=", "")); rc.AnnounceSDP(sdp); rc.AddHeaders.Remove("Apple-Challenge"); Hashtable ht = rc.Setup(); string aj = (string)ht["Audio-Jack-Status"]; if (aj == null) { throw new Exception("Audio-Jack-Status is missing"); } string [] ptokens = aj.Split(new char[] { ';' }); for (int i = 0; i < ptokens.Length; i++) { string [] ctokens = ptokens[i].Split(new char[] { '=' }); for (int j = 0; j < ctokens.Length; j++) { if (ctokens.Length == 1 && ctokens[0].Trim().Equals("connected")) { ajstatus = JACK_STATUS_CONNECTED; } else if (ctokens.Length == 2 && ctokens[0].Trim().Equals("type")) { if (ctokens[1].Trim().Equals("digital")) { ajtype = JACK_TYPE_DIGITAL; } } } } rc.Record(); UpdateVolume(); tcdata = new TcpClient(); tcdata.Connect(host, rc.ServerPort); nsdata = tcdata.GetStream(); }