//Todo, cleanup and allow existing Rtp and Rtcp socket. /// <summary> /// Will create a <see cref="RtpClient"/> based on the given parameters /// </summary> /// <param name="sessionDescription"></param> /// <param name="sharedMemory"></param> /// <param name="incomingEvents"></param> /// <param name="rtcpEnabled"></param> /// <returns></returns> public static RtpClient FromSessionDescription(Sdp.SessionDescription sessionDescription, Common.MemorySegment sharedMemory = null, bool incomingEvents = true, bool rtcpEnabled = true, System.Net.Sockets.Socket existingSocket = null, int?rtpPort = null, int?rtcpPort = null, int remoteSsrc = 0, int minimumSequentialRtpPackets = 2, bool connect = true, System.Action <System.Net.Sockets.Socket> configure = null) { if (Common.IDisposedExtensions.IsNullOrDisposed(sessionDescription)) { throw new System.ArgumentNullException("sessionDescription"); } Sdp.Lines.SessionConnectionLine connectionLine = new Sdp.Lines.SessionConnectionLine(sessionDescription.ConnectionLine); System.Net.IPAddress remoteIp = System.Net.IPAddress.Parse(connectionLine.Host), localIp; System.Net.NetworkInformation.NetworkInterface localInterface; //If the socket is NOT null and IS BOUND use the localIp of the same address family if (object.ReferenceEquals(existingSocket, null).Equals(false) && existingSocket.IsBound) { //If the socket is IP based if (existingSocket.LocalEndPoint is System.Net.IPEndPoint) { //Take the localIp from the LocalEndPoint localIp = (existingSocket.LocalEndPoint as System.Net.IPEndPoint).Address; } else { throw new System.NotSupportedException("Please create an issue for your use case."); } } else // There is no socket existing. { //If the remote address is the broadcast address or the remote address is multicast if (System.Net.IPAddress.Broadcast.Equals(remoteIp) || IPAddressExtensions.IsMulticast(remoteIp)) { //This interface should be the interface you plan on using for the Rtp communication localIp = SocketExtensions.GetFirstMulticastIPAddress(remoteIp.AddressFamily, out localInterface); } else { //This interface should be the interface you plan on using for the Rtp communication localIp = SocketExtensions.GetFirstUnicastIPAddress(remoteIp.AddressFamily, out localInterface); } } RtpClient client = new RtpClient(sharedMemory, incomingEvents); byte lastChannel = 0; //Todo, check for session level ssrc //if (remoteSsrc.Equals(0)) //{ // //Sdp.SessionDescriptionLine ssrcLine = sessionDescription.SsrcGroupLine; // SsrcLine @ the session level could imply Group //} //For each MediaDescription in the SessionDescription foreach (Media.Sdp.MediaDescription md in sessionDescription.MediaDescriptions) { //Make a RtpClient.TransportContext from the MediaDescription being parsed. TransportContext tc = TransportContext.FromMediaDescription(sessionDescription, lastChannel++, lastChannel++, md, rtcpEnabled, remoteSsrc, minimumSequentialRtpPackets, localIp, remoteIp, //The localIp and remoteIp rtpPort, rtcpPort, //The remote ports to receive data from connect, existingSocket, configure); //Try to add the context try { client.AddContext(tc); } catch (System.Exception ex) { TaggedExceptionExtensions.RaiseTaggedException(tc, "See Tag, Could not add the created TransportContext.", ex); } } //Return the participant return(client); }