Beispiel #1
0
        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));
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        static async Task Main()
        {
            Console.WriteLine("Janus Echo Test Demo");

            AddConsoleLogger();

            CancellationTokenSource cts = new CancellationTokenSource();
            bool isFormActivated        = false;

            #region Set up a simple Windows Form with two picture boxes.

            var form = new Form();
            form.AutoSize = true;
            form.BackgroundImageLayout = ImageLayout.Center;
            var localVideoPicBox = new PictureBox
            {
                Size     = new Size(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT),
                Location = new Point(0, 0),
                Visible  = true
            };
            var remoteVideoPicBox = new PictureBox
            {
                Size     = new Size(VIDEO_FRAME_WIDTH, VIDEO_FRAME_HEIGHT),
                Location = new Point(0, VIDEO_FRAME_HEIGHT),
                Visible  = true
            };
            form.Controls.Add(localVideoPicBox);
            form.Controls.Add(remoteVideoPicBox);

            Application.EnableVisualStyles();
            ThreadPool.QueueUserWorkItem(delegate { Application.Run(form); });
            form.FormClosing += (sender, e) => isFormActivated = false;
            form.Activated   += (sender, e) => isFormActivated = true;

            #endregion

            Console.WriteLine("Creating peer connection.");
            RTCPeerConnection pc = new RTCPeerConnection(null);

            var videoSource = new VideoTestPatternSource(new VpxVideoEncoder());
            var videoSink   = new VideoEncoderEndPoint();

            MediaStreamTrack videoTrack = new MediaStreamTrack(videoSink.GetVideoSourceFormats(), MediaStreamStatusEnum.SendRecv);
            pc.addTrack(videoTrack);
            pc.OnVideoFrameReceived += videoSink.GotVideoFrame;
            videoSource.OnVideoSourceEncodedSample += pc.SendVideo;

            pc.OnVideoFormatsNegotiated += (formats) =>
            {
                videoSink.SetVideoSourceFormat(formats.First());
                videoSource.SetVideoSourceFormat(formats.First());
            };
            pc.OnTimeout += (mediaType) => Console.WriteLine($"Peer connection timeout on media {mediaType}.");
            pc.oniceconnectionstatechange += (state) => Console.WriteLine($"ICE connection state changed to {state}.");
            pc.onconnectionstatechange    += async(state) =>
            {
                Console.WriteLine($"Peer connection connected changed to {state}.");

                if (state == RTCPeerConnectionState.closed || state == RTCPeerConnectionState.failed)
                {
                    await videoSource.CloseVideo().ConfigureAwait(false);

                    videoSource.Dispose();
                }
            };

            #region Wire up the video source and sink to the picutre boxes.

            videoSource.OnVideoSourceRawSample += (uint durationMilliseconds, int width, int height, byte[] sample, VideoPixelFormatsEnum pixelFormat) =>
            {
                if (isFormActivated)
                {
                    form?.BeginInvoke(new Action(() =>
                    {
                        if (form.Handle != IntPtr.Zero)
                        {
                            unsafe
                            {
                                fixed(byte *s = sample)
                                {
                                    var bmpImage           = new Bitmap(width, height, width * 3, PixelFormat.Format24bppRgb, (IntPtr)s);
                                    localVideoPicBox.Image = bmpImage;
                                }
                            }
                        }
                    }));
                }
            };

            videoSink.OnVideoSinkDecodedSample += (byte[] bmp, uint width, uint height, int stride, VideoPixelFormatsEnum pixelFormat) =>
            {
                if (isFormActivated)
                {
                    form.BeginInvoke(new Action(() =>
                    {
                        unsafe
                        {
                            fixed(byte *s = bmp)
                            {
                                Bitmap bmpImage         = new Bitmap((int)width, (int)height, (int)(bmp.Length / height), PixelFormat.Format24bppRgb, (IntPtr)s);
                                remoteVideoPicBox.Image = bmpImage;
                            }
                        }
                    }));
                }
            };

            #endregion

            var offer = pc.CreateOffer(null);
            await pc.setLocalDescription(new RTCSessionDescriptionInit { type = RTCSdpType.offer, sdp = offer.ToString() }).ConfigureAwait(false);

            Console.WriteLine($"SDP Offer: {pc.localDescription.sdp}");

            await videoSource.StartVideo().ConfigureAwait(false);

            if (_useJanusRest)
            {
                JanusRestClient janusClient = new JanusRestClient(
                    JANUS_BASE_URI,
                    SIPSorcery.LogFactory.CreateLogger <JanusRestClient>(),
                    cts.Token);

                //var serverInfo = await janusClient.GetServerInfo().ConfigureAwait(false);
                //Console.WriteLine($"Name={serverInfo.name}.");
                //Console.WriteLine($"Version={serverInfo.version}.");

                janusClient.OnJanusEvent += async(resp) =>
                {
                    if (resp.jsep != null)
                    {
                        Console.WriteLine($"get event jsep={resp.jsep.type}.");

                        Console.WriteLine($"SDP Answer: {resp.jsep.sdp}");
                        var result = pc.setRemoteDescription(new RTCSessionDescriptionInit {
                            type = RTCSdpType.answer, sdp = resp.jsep.sdp
                        });
                        Console.WriteLine($"SDP Answer: {pc.remoteDescription.sdp}");

                        if (result == SetDescriptionResultEnum.OK)
                        {
                            Console.WriteLine("Starting peer connection.");
                            await pc.Start().ConfigureAwait(false);
                        }
                        else
                        {
                            Console.WriteLine($"Error setting remote SDP description {result}.");
                        }
                    }
                };

                await janusClient.StartSession().ConfigureAwait(false);

                await janusClient.StartEcho(offer.ToString()).ConfigureAwait(false);
            }
            else
            {
                //RestClient signalingClient = new RestClient($"{WEBRTC_SIGNALING_JANUS_URL}?duration=15");
                RestClient signalingClient = new RestClient($"{WEBRTC_SIGNALING_JANUS_URL}");
                var        echoTestReq     = new RestRequest(string.Empty, Method.POST, DataFormat.Json);
                echoTestReq.AddJsonBody(pc.localDescription.sdp.ToString());
                var echoTestResp = await signalingClient.ExecutePostAsync <string>(echoTestReq).ConfigureAwait(false);

                if (echoTestResp.IsSuccessful)
                {
                    var sdpAnswer = echoTestResp.Data;
                    Console.WriteLine($"SDP Answer: {sdpAnswer}");
                    var result = pc.setRemoteDescription(new RTCSessionDescriptionInit {
                        type = RTCSdpType.answer, sdp = sdpAnswer
                    });
                    Console.WriteLine($"SDP Answer: {pc.remoteDescription.sdp}");

                    if (result == SetDescriptionResultEnum.OK)
                    {
                        Console.WriteLine("Starting peer connection.");
                        await pc.Start().ConfigureAwait(false);
                    }
                    else
                    {
                        Console.WriteLine($"Error setting remote SDP description {result}.");
                    }
                }
                else
                {
                    Console.WriteLine($"Janus echo test plugin request failed {echoTestResp.ErrorMessage}.");
                }
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();

            isFormActivated = false;
            cts.Cancel();

            //await janusClient.DestroySession().ConfigureAwait(false);
        }