public override string GenerateSDPDescription() { StringBuilder sb = new StringBuilder(); TimeVal timeVal = new TimeVal(); RTPTime.GetTimestamp(ref timeVal); sb.Append("v= 0\r\n"). AppendFormat("o=- {0}{1:06} 1 IN IP4 {2}\r\n", timeVal.tv_sec, timeVal.tv_usec, SocketExtensions.GetLocalIPV4Address()). AppendFormat("s=Session streamed by \"{0}\"\r\n", RTSPServer.ServerVersion). AppendFormat("i={0}\r\n", Name). Append("t=0 0\r\n"). AppendFormat("a=tool:{0}\r\n", RTSPServer.ServerVersion). Append("a=type:broadcast\r\n"). Append("a=control:*\r\n"). AppendFormat("a=source-filter: incl IN IP4 * {0}\r\n", SocketExtensions.GetLocalIPV4Address()). Append("a=rtcp-unicast: reflection\r\n"). Append("a=range:npt=0-\r\n"). AppendFormat("a=x-qt-text-nam:Session streamed by {0}\r\n", RTSPServer.ServerVersion). AppendFormat("a=x-qt-text-inf:{0}\r\n", Name). AppendFormat("m=video {0} RTP/AVP 96\r\n", ServerRTPPort). AppendFormat("c=IN IP4 {0}/255\r\n", MulticastAdress). Append("b=AS:500\r\n"). Append("a=rtpmap:96 H264/90000\r\n"). Append("a=fmtp:96 packetization-mode=1;profile-level-id=640028;sprop-parameter-sets=J2QAKKwrQCgC3QDxImo=,KO4Pyw==\r\n"). Append("a=control:track1\r\n"); return(sb.ToString()); }
public async Task <bool> Play(RTSPRequestParser parser) { string stream = parser.Media; ServerMediaSession session = _connection.Server.lookupServerMediaSession(stream); if (session == null) { _connection.HandleNotFound(parser); return(false); } // Look up information for the specified subsession (track): ServerMediaSubsession subsession; subsession = session.LookupSubSession(stream); ushort rtpSeqNum = 0; uint rtpTimestamp = 0; _rtpStream = subsession.GetStreamInstance(); rtpSeqNum = _rtpStream.CurrentSeqNo(); rtpTimestamp = _rtpStream.CurrentTimeStamp(); // presetNextTimestamp(); Playing = true; await _rtpStream.AddDestination(this, _destinations); if (_destinations.isTCP) { _connection.RegisterFilter(_rtpStream); } StringBuilder sb = new StringBuilder(); sb.Append("RTSP/1.0 200 OK\r\n"); sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion); sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]); sb.AppendFormat("Session: {0}\r\n", parser.Headers["SESSION"]); sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n"); sb.Append("Cache-Control: must-revalidate\r\n"); sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n"); sb.Append("Expires: Sun, 23 Dec 2018 12:01:28 GMT\r\n"); sb.Append("Range: npt=0.000-\r\n"). AppendFormat("RTP-Info: url=rtsp://{0}:{1}/{2}/track1;seq={3};rtptime={4}\r\n\r\n", SocketExtensions.GetLocalIPV4Address(), _connection.Server.Port, subsession.Name, rtpSeqNum, rtpTimestamp); string reply = sb.ToString(); _connection.SendResponse(reply); return(true); }
private bool Describes(RTSPRequestParser parser) { // Begin by looking up the "ServerMediaSession" object for the specified "urlTotalSuffix": string media = parser.Media; ServerMediaSession session = Server.lookupServerMediaSession(media); if (session == null) { HandleNotFound(parser); return(false); } // Look up information for the specified subsession (track): ServerMediaSubsession subsession; media = media.TrimEnd('/'); // parser.Uri.Segments[2].TrimStart('/'); subsession = session.LookupSubSession(media); var sdp = subsession.GenerateSDPDescription(); StringBuilder sb = new StringBuilder(); sb.Append("RTSP/1.0 200 OK\r\n"); sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion); sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]); sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n"); sb.Append("Cache-Control: must-revalidate\r\n"); sb.AppendFormat("Content-length: {0}\r\n", sdp.Length); sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n"); sb.Append("Expires: Sat, 22 Dec 2018 16:18:03 GMT\r\n"); sb.Append("Content-Type: application/sdp\r\n"). Append("x-Accept-Retransmit: our-retransmit\r\n"). Append("x-Accept-Dynamic-Rate: 1\r\n"). AppendFormat("Content-Base: rtsp://{0}:{1}/{2}\r\n\r\n", SocketExtensions.GetLocalIPV4Address(), Server.Port, subsession.Name). Append(sdp); var str = sb.ToString(); SendResponse(str); return(true); }
public bool Setup(TcpClient tcpSocket, RTSPRequestParser parser) { string media = parser.Media; ServerMediaSession session = _connection.Server.lookupServerMediaSession(media); if (session == null) { _connection.HandleNotFound(parser); return(false); } // Look up information for the specified subsession (track): ServerMediaSubsession subsession = session.LookupSubSession(media); Socket socket = null; if (String.Compare(parser.TransportType, "RTP/AVP/TCP") == 0) { socket = tcpSocket.Client; IsRTPOverTCP = true; } if ((subsession.IsMulticast && parser.TransportMode == "UNICAST") || (!subsession.IsMulticast && parser.TransportMode == "MULTICAST")) { _connection.HandleUnsupportedTransport(parser); return(false); } int clientRTPPort = parser.ClientPort1; int clientRTCPPort = parser.ClientPort2; int serverRTPPort; int serverRTCPPort; string multiCastAddress; var clientAddress = tcpSocket.Client.RemoteEndPoint as IPEndPoint; subsession.GetStreamParameters(out serverRTPPort, out serverRTCPPort, out multiCastAddress); SetupDestinations(socket, clientAddress, null, clientRTPPort, clientRTCPPort, (byte)parser.Channel1, (byte)parser.Channel2); StringBuilder sb = new StringBuilder(); sb.Append("RTSP/1.0 200 OK\r\n"); sb.AppendFormat("Server: {0}\r\n", RTSPServer.ServerVersion); sb.AppendFormat("Cseq: {0}\r\n", parser.Headers["CSEQ"]); var localIP = SocketExtensions.GetLocalIPV4Address(); if (parser.TransportMode == "UNICAST") { sb.AppendFormat("Session: {0}\r\n", SessionId); sb.Append("Last-Modified: Tue, 30 Aug 2016 01:33:17 GMT\r\n"); sb.Append("Cache-Control: must-revalidate\r\n"); sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n"); sb.Append("Expires: Sun, 23 Dec 2018 12:01:28 GMT\r\n"); if (socket == null) { // UDP sb.AppendFormat("Transport: RTP/AVP;unicast;destination={0};source={1};client_port={2}-{3};server_port={4}-{5};\r\n\r\n", clientAddress.Address, localIP, parser.ClientPort1, parser.ClientPort2, serverRTPPort, serverRTCPPort); } else { // TCP sb.AppendFormat("Transport: RTP/AVP/TCP;unicast;destination={0};source={1};interleaved={2}-{3}\r\n\r\n", clientAddress.Address, localIP, parser.Channel1, parser.Channel2); } } // Multicast else { sb.Append("Date: Sat, 22 Dec 2018 16:18:03 GMT\r\n"); sb.AppendFormat("Transport: RTP/AVP;multicast;destination={0};source={1};port={2}-{3};ttl=255\r\n", multiCastAddress, localIP, serverRTPPort, serverRTCPPort). AppendFormat("Session: {0};timeout=65\r\n\r\n", SessionId); } var reply = sb.ToString(); _connection.SendResponse(reply); return(true); }