public async Task <RTCSessionDescriptionInit> GetOffer(string id) { if (string.IsNullOrWhiteSpace(id)) { throw new ArgumentNullException("id", "A unique ID parameter must be supplied when creating a new peer connection."); } else if (_peerConnections.ContainsKey(id)) { throw new ArgumentNullException("id", "The specified peer connection ID is already in use."); } RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { X_CertificatePath = DTLS_CERTIFICATE_PATH, X_KeyPath = DTLS_KEY_PATH, X_Fingerprint = DTLS_CERTIFICATE_FINGERPRINT } } }; var peerConnection = new RTCPeerConnection(pcConfiguration); var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH); MediaStreamTrack audioTrack = new MediaStreamTrack("0", SDPMediaTypesEnum.audio, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.PCMU) }, MediaStreamStatusEnum.RecvOnly); peerConnection.addTrack(audioTrack); //peerConnection.OnRtpPacketReceived += (SDPMediaTypesEnum media, RTPPacket rtpPkt) => _logger.LogDebug($"RTP {media} pkt received, SSRC {rtpPkt.Header.SyncSource}, SeqNum {rtpPkt.Header.SequenceNumber}."); //peerConnection.OnReceiveReport += RtpSession_OnReceiveReport; //peerConnection.OnSendReport += RtpSession_OnSendReport; peerConnection.OnTimeout += (mediaType) => { peerConnection.Close("remote timeout"); dtls.Shutdown(); }; peerConnection.onconnectionstatechange += (state) => { if (state == RTCPeerConnectionState.closed || state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed) { //peerConnection.OnReceiveReport -= RtpSession_OnReceiveReport; //peerConnection.OnSendReport -= RtpSession_OnSendReport; _logger.LogDebug($"Peer connection {id} closed."); _peerConnections.TryRemove(id, out _); } else if (state == RTCPeerConnectionState.connected) { _logger.LogDebug("Peer connection connected."); } }; _ = Task <bool> .Run(() => Task.FromResult(DoDtlsHandshake(peerConnection, dtls))) .ContinueWith((t) => { _logger.LogDebug($"dtls handshake result {t.Result}."); if (t.Result) { var remoteEP = peerConnection.IceSession.ConnectedRemoteEndPoint; peerConnection.SetDestination(SDPMediaTypesEnum.audio, remoteEP, remoteEP); } else { dtls.Shutdown(); peerConnection.Close("dtls handshake failed."); } }); var offerSdp = await peerConnection.createOffer(null); await peerConnection.setLocalDescription(offerSdp); _peerConnections.TryAdd(id, peerConnection); return(offerSdp); }
static async Task Main() { Console.WriteLine("SIPSorcery sip.js Demo"); AddConsoleLogger(); var sipTransport = new SIPTransport(); EnableTraceLogs(sipTransport); var sipChannel = new SIPWebSocketChannel(IPAddress.Loopback, 80); var wssCertificate = new System.Security.Cryptography.X509Certificates.X509Certificate2("localhost.pfx"); var sipChannelSecure = new SIPWebSocketChannel(IPAddress.Loopback, 443, wssCertificate); sipTransport.AddSIPChannel(sipChannel); sipTransport.AddSIPChannel(sipChannelSecure); var userAgent = new SIPUserAgent(sipTransport, null, true); userAgent.OnIncomingCall += async(ua, req) => { Log.LogDebug($"Auto-answering incoming call from {req.Header.From}."); var uas = userAgent.AcceptCall(req); RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { X_CertificatePath = DTLS_CERTIFICATE_PATH, X_KeyPath = DTLS_KEY_PATH, X_Fingerprint = DTLS_CERTIFICATE_FINGERPRINT } }, //X_RemoteSignallingAddress = context.UserEndPoint.Address, //iceServers = new List<RTCIceServer> { new RTCIceServer { urls = SIPSORCERY_STUN_SERVER } } }; var peerConnection = new RTCPeerConnection(pcConfiguration); var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH); peerConnection.OnTimeout += (mediaType) => { peerConnection.Close("remote timeout"); }; peerConnection.oniceconnectionstatechange += async(state) => { Log.LogDebug($"ICE connection state change to {state}."); if (state == RTCIceConnectionState.connected) { var remoteEndPoint = peerConnection.AudioDestinationEndPoint; Log.LogInformation($"ICE connected to remote end point {remoteEndPoint}."); await Task.Run(() => DoDtlsHandshake(peerConnection, dtls)) .ContinueWith((dtlsResult) => { Log.LogDebug($"dtls handshake result {dtlsResult.Result}."); if (dtlsResult.Result) { var remoteEP = peerConnection.AudioDestinationEndPoint; peerConnection.SetDestination(SDPMediaTypesEnum.audio, remoteEP, remoteEP); } else { dtls.Shutdown(); peerConnection.Close("dtls handshake failed."); } }); } }; peerConnection.onconnectionstatechange += (state) => { if (state == RTCPeerConnectionState.connected) { var remoteEP = peerConnection.AudioDestinationEndPoint; Log.LogDebug($"DTLS connected on {remoteEP}."); peerConnection.SetDestination(SDPMediaTypesEnum.audio, remoteEP, remoteEP); peerConnection.SetDestination(SDPMediaTypesEnum.video, remoteEP, remoteEP); peerConnection.OnReceiveReport += RtpSession_OnReceiveReport; peerConnection.OnSendReport += RtpSession_OnSendReport; // peerConnection.OnRtpPacketReceived += OnRtpPacketReceived; } }; MediaStreamTrack audioTrack = new MediaStreamTrack(SDPMediaTypesEnum.audio, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.PCMU) }, MediaStreamStatusEnum.SendRecv); peerConnection.addTrack(audioTrack); //MediaStreamTrack videoTrack = new MediaStreamTrack("1", SDPMediaTypesEnum.video, false, new List<SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }, MediaStreamStatusEnum.Inactive); //peerConnection.addTrack(videoTrack); var answerResult = await userAgent.Answer(uas, peerConnection); }; Console.Write("press any key to exit..."); Console.Read(); sipTransport.Shutdown(); }
private static async Task <RTCPeerConnection> StartPeerConnection() { RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { X_CertificatePath = DTLS_CERTIFICATE_PATH, X_KeyPath = DTLS_KEY_PATH, X_Fingerprint = DTLS_CERTIFICATE_FINGERPRINT } } }; var peerConnection = new RTCPeerConnection(pcConfiguration); MediaStreamTrack videoTrack = new MediaStreamTrack( SDPMediaTypesEnum.video, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }, MediaStreamStatusEnum.SendOnly); peerConnection.addTrack(videoTrack); peerConnection.OnReceiveReport += RtpSession_OnReceiveReport; peerConnection.OnSendReport += RtpSession_OnSendReport; //peerConnection.OnRtcpBye += (reason) => //{ // logger.LogInformation("RTCP BYE report received from remote peer."); // peerConnection.Close(reason); // dtls.Shutdown(); //}; peerConnection.OnTimeout += (mediaType) => { peerConnection.Close("remote timeout"); }; peerConnection.onconnectionstatechange += async(state) => { if (state == RTCPeerConnectionState.closed || state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed) { OnTestPatternSampleReady -= peerConnection.SendMedia; peerConnection.OnReceiveReport -= RtpSession_OnReceiveReport; peerConnection.OnSendReport -= RtpSession_OnSendReport; } else if (state == RTCPeerConnectionState.connected) { // The DTLS handshake completed. logger.LogDebug("Peer connection connected."); OnTestPatternSampleReady += peerConnection.SendMedia; await peerConnection.Start(); if (_sendTestPatternTimer == null) { _sendTestPatternTimer = new Timer(SendTestPattern, null, 0, TEST_PATTERN_SPACING_MILLISECONDS); } } }; peerConnection.oniceconnectionstatechange += (state) => { logger.LogDebug($"ICE connection state change {state}."); // The ICE connectivity check completed successfully. if (state == RTCIceConnectionState.connected) { var remoteEP = peerConnection.AudioDestinationEndPoint; peerConnection.SetDestination(SDPMediaTypesEnum.audio, remoteEP, remoteEP); } }; var offerSdp = peerConnection.createOffer(null); await peerConnection.setLocalDescription(offerSdp); logger.LogDebug(offerSdp.sdp); return(peerConnection); }
private static async Task <RTCPeerConnection> SendSDPOffer(WebSocketContext context) { logger.LogDebug($"Web socket client connection from {context.UserEndPoint}."); RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { X_CertificatePath = DTLS_CERTIFICATE_PATH, X_KeyPath = DTLS_KEY_PATH, X_Fingerprint = DTLS_CERTIFICATE_FINGERPRINT } } }; var peerConnection = new RTCPeerConnection(pcConfiguration); var dtls = new DtlsHandshake(DTLS_CERTIFICATE_PATH, DTLS_KEY_PATH); MediaStreamTrack audioTrack = new MediaStreamTrack("0", SDPMediaTypesEnum.audio, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.PCMU) }); peerConnection.addTrack(audioTrack); MediaStreamTrack videoTrack = new MediaStreamTrack("1", SDPMediaTypesEnum.video, false, new List <SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }); peerConnection.addTrack(videoTrack); peerConnection.OnReceiveReport += RtpSession_OnReceiveReport; peerConnection.OnSendReport += RtpSession_OnSendReport; peerConnection.OnTimeout += (mediaType) => { peerConnection.Close("remote timeout"); dtls.Shutdown(); }; peerConnection.onconnectionstatechange += (state) => { if (state == RTCPeerConnectionState.closed || state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed) { logger.LogDebug($"RTC peer connection was closed."); OnMediaSampleReady -= peerConnection.SendMedia; peerConnection.OnReceiveReport -= RtpSession_OnReceiveReport; peerConnection.OnSendReport -= RtpSession_OnSendReport; } else if (state == RTCPeerConnectionState.connected) { logger.LogDebug("Peer connection connected."); OnMediaSampleReady += peerConnection.SendMedia; } }; peerConnection.oniceconnectionstatechange += (state) => { if (state == RTCIceConnectionState.connected) { logger.LogDebug("Starting DTLS handshake task."); bool dtlsResult = false; Task.Run(async() => dtlsResult = await DoDtlsHandshake(peerConnection, dtls)) .ContinueWith((t) => { logger.LogDebug($"dtls handshake result {dtlsResult}."); if (dtlsResult) { peerConnection.SetDestination(SDPMediaTypesEnum.audio, peerConnection.IceSession.ConnectedRemoteEndPoint, peerConnection.IceSession.ConnectedRemoteEndPoint); } else { dtls.Shutdown(); peerConnection.Close("dtls handshake failed."); } }); } }; var offerInit = await peerConnection.createOffer(null); await peerConnection.setLocalDescription(offerInit); logger.LogDebug($"Sending SDP offer to client {context.UserEndPoint}."); context.WebSocket.Send(offerInit.sdp); return(peerConnection); }
private static RTCPeerConnection CreatePeerConnection() { RTCConfiguration pcConfiguration = new RTCConfiguration { certificates = new List <RTCCertificate> { new RTCCertificate { X_CertificatePath = DTLS_CERTIFICATE_PATH, X_KeyPath = DTLS_KEY_PATH, X_Fingerprint = DTLS_CERTIFICATE_FINGERPRINT } } }; var peerConnection = new RTCPeerConnection(pcConfiguration); peerConnection.OnReceiveReport += RtpSession_OnReceiveReport; peerConnection.OnSendReport += RtpSession_OnSendReport; peerConnection.onconnectionstatechange += (state) => { if (state == RTCPeerConnectionState.closed || state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed) { OnMediaSampleReady -= peerConnection.SendMedia; peerConnection.OnReceiveReport -= RtpSession_OnReceiveReport; peerConnection.OnSendReport -= RtpSession_OnSendReport; } else if (state == RTCPeerConnectionState.connected) { logger.LogDebug("Peer connection connected."); OnMediaSampleReady += peerConnection.SendMedia; } }; peerConnection.oniceconnectionstatechange += (state) => { if (state == RTCIceConnectionState.connected) { logger.LogDebug("Starting DTLS handshake task."); bool dtlsResult = false; Task.Run(() => dtlsResult = DoDtlsHandshake(peerConnection)) .ContinueWith((t) => { logger.LogDebug($"dtls handshake result {dtlsResult}."); if (dtlsResult) { peerConnection.SetDestination(SDPMediaTypesEnum.audio, peerConnection.IceSession.ConnectedRemoteEndPoint, peerConnection.IceSession.ConnectedRemoteEndPoint); } else { peerConnection.Close("dtls handshake failed."); } }); } }; return(peerConnection); }