private static Task <RTCPeerConnection> CreatePeerConnection(X509Certificate2 cert) { //RTCConfiguration config = new RTCConfiguration //{ // iceServers = new List<RTCIceServer> { new RTCIceServer { urls = STUN_URL } }, // certificates = new List<RTCCertificate> { new RTCCertificate { Certificate = cert } } //}; //var pc = new RTCPeerConnection(config); var pc = new RTCPeerConnection(null); var testPatternSource = new VideoTestPatternSource(new SIPSorceryMedia.Encoders.VideoEncoder()); testPatternSource.SetFrameRate(60); //testPatternSource.SetMaxFrameRate(true); //var videoEndPoint = new SIPSorceryMedia.FFmpeg.FFmpegVideoEndPoint(); //videoEndPoint.RestrictFormats(format => format.Codec == VideoCodecsEnum.H264); //var videoEndPoint = new SIPSorceryMedia.Windows.WindowsEncoderEndPoint(); //var videoEndPoint = new SIPSorceryMedia.Encoders.VideoEncoderEndPoint(); MediaStreamTrack track = new MediaStreamTrack(testPatternSource.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(track); //testPatternSource.OnVideoSourceRawSample += videoEndPoint.ExternalVideoSourceRawSample; testPatternSource.OnVideoSourceRawSample += MesasureTestPatternSourceFrameRate; testPatternSource.OnVideoSourceEncodedSample += pc.SendVideo; pc.OnVideoFormatsNegotiated += (formats) => testPatternSource.SetVideoSourceFormat(formats.First()); pc.onconnectionstatechange += async(state) => { logger.LogDebug($"Peer connection state change to {state}."); if (state == RTCPeerConnectionState.failed) { pc.Close("ice disconnection"); } else if (state == RTCPeerConnectionState.closed) { await testPatternSource.CloseVideo(); await testPatternSource.CloseVideo(); testPatternSource.Dispose(); } else if (state == RTCPeerConnectionState.connected) { await testPatternSource.StartVideo(); await testPatternSource.StartVideo(); } }; // Diagnostics. //pc.OnReceiveReport += (re, media, rr) => logger.LogDebug($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}"); //pc.OnSendReport += (media, sr) => logger.LogDebug($"RTCP Send for {media}\n{sr.GetDebugSummary()}"); //pc.GetRtpChannel().OnStunMessageReceived += (msg, ep, isRelay) => logger.LogDebug($"STUN {msg.Header.MessageType} received from {ep}."); pc.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}."); return(Task.FromResult(pc)); }
static async Task Main() { Console.WriteLine("SIPSorcery Asterisk + ICE Demo"); AddConsoleLogger(); CancellationTokenSource exitCts = new CancellationTokenSource(); var sipTransport = new SIPTransport(); EnableTraceLogs(sipTransport); var userAgent = new SIPUserAgent(sipTransport, null); userAgent.ClientCallFailed += (uac, error, sipResponse) => Console.WriteLine($"Call failed {error}."); userAgent.OnCallHungup += async(dialog) => { // Give time for the BYE response before exiting. await Task.Delay(1000); exitCts.Cancel(); }; var audioExtras = new AudioExtrasSource(); audioExtras.SetSource(AudioSourcesEnum.PinkNoise); var testPattern = new VideoTestPatternSource(new VpxVideoEncoder()); var pc = new RTCPeerConnection(null); pc.OnAudioFormatsNegotiated += (formats) => audioExtras.SetAudioSourceFormat(formats.First()); pc.OnVideoFormatsNegotiated += (formats) => testPattern.SetVideoSourceFormat(formats.First()); var audioTrack = new MediaStreamTrack(audioExtras.GetAudioSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(audioTrack); audioExtras.OnAudioSourceEncodedSample += pc.SendAudio; var videoTrack = new MediaStreamTrack(testPattern.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly); pc.addTrack(videoTrack); testPattern.OnVideoSourceEncodedSample += pc.SendVideo; // Diagnostics. pc.OnReceiveReport += (re, media, rr) => Console.WriteLine($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}"); pc.OnSendReport += (media, sr) => Console.WriteLine($"RTCP Send for {media}\n{sr.GetDebugSummary()}"); pc.GetRtpChannel().OnStunMessageReceived += (msg, ep, isRelay) => Console.WriteLine($"STUN {msg.Header.MessageType} received from {ep}."); pc.oniceconnectionstatechange += (state) => Console.WriteLine($"ICE connection state change to {state}."); // ICE connection state handler. pc.onconnectionstatechange += (state) => { Console.WriteLine($"Peer connection state change to {state}."); if (state == RTCPeerConnectionState.connected) { audioExtras.StartAudio(); testPattern.StartVideo(); } else if (state == RTCPeerConnectionState.failed) { if (userAgent.IsCallActive) { Console.WriteLine("ICE connection failed, hanging up active call."); userAgent.Hangup(); } } }; // Place the call and wait for the result. var callTask = userAgent.Call(DESTINATION, USERNAME, PASSWORD, pc); Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e) { e.Cancel = true; if (userAgent != null) { if (userAgent.IsCalling || userAgent.IsRinging) { Console.WriteLine("Cancelling in progress call."); userAgent.Cancel(); } else if (userAgent.IsCallActive) { Console.WriteLine("Hanging up established call."); userAgent.Hangup(); } } ; exitCts.Cancel(); }; Console.WriteLine("press ctrl-c to exit..."); bool callResult = await callTask; if (callResult) { Console.WriteLine($"Call to {DESTINATION} succeeded."); exitCts.Token.WaitHandle.WaitOne(); } else { Console.WriteLine($"Call to {DESTINATION} failed."); } Console.WriteLine("Exiting..."); if (userAgent?.IsHangingUp == true) { Console.WriteLine("Waiting 1s for the call hangup or cancel to complete..."); await Task.Delay(1000); } // Clean up. sipTransport.Shutdown(); }