Ejemplo n.º 1
0
        public async Task SctpError()
        {
            // Setup
            var config = new PeerConnectionConfiguration();
            var pc1    = new PeerConnection();
            var pc2    = new PeerConnection();
            await pc1.InitializeAsync(config);

            await pc2.InitializeAsync(config);

            pc1.LocalSdpReadytoSend += async(string type, string sdp) =>
            {
                await pc2.SetRemoteDescriptionAsync(type, sdp);

                if (type == "offer")
                {
                    pc2.CreateAnswer();
                }
            };
            pc2.LocalSdpReadytoSend += async(string type, string sdp) =>
            {
                await pc1.SetRemoteDescriptionAsync(type, sdp);

                if (type == "offer")
                {
                    pc1.CreateAnswer();
                }
            };
            pc1.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid)
                                           => pc2.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
            pc2.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid)
                                           => pc1.AddIceCandidate(sdpMid, sdpMlineindex, candidate);

            // Connect
            {
                var c1 = new ManualResetEventSlim(false);
                var c2 = new ManualResetEventSlim(false);
                pc1.Connected += () => c1.Set();
                pc2.Connected += () => c2.Set();
                Assert.True(pc1.CreateOffer());
                Assert.True(c1.Wait(TimeSpan.FromSeconds(60.0)));
                Assert.True(c2.Wait(TimeSpan.FromSeconds(60.0)));
                Assert.True(pc1.IsConnected);
                Assert.True(pc1.IsConnected);
            }

            // Try to add a data channel. This should fail because SCTP was not negotiated.
            Assert.ThrowsAsync <SctpNotNegotiatedException>(async() => await pc1.AddDataChannelAsync("dummy", false, false));
            Assert.ThrowsAsync <SctpNotNegotiatedException>(async() => await pc1.AddDataChannelAsync(42, "dummy", false, false));

            // Clean-up
            pc1.Close();
            pc1.Dispose();
            pc2.Close();
            pc2.Dispose();
        }
        protected async Task MakeICECall(PeerConnection pc1, PeerConnection pc2)
        {
            var evExchangeCompleted = new ManualResetEventSlim(initialState: false);

            pc1.LocalSdpReadytoSend += async(SdpMessage message) =>
            {
                await pc2.SetRemoteDescriptionAsync(message);

                if (message.Type == SdpMessageType.Offer)
                {
                    pc2.CreateAnswer();
                }
                else
                {
                    evExchangeCompleted.Set();
                }
            };
            pc2.LocalSdpReadytoSend += async(SdpMessage message) =>
            {
                await pc1.SetRemoteDescriptionAsync(message);

                if (message.Type == SdpMessageType.Offer)
                {
                    pc1.CreateAnswer();
                }
                else
                {
                    evExchangeCompleted.Set();
                }
            };
            pc1.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid) =>
            {
                pc2.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
            };
            pc2.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid) =>
            {
                pc1.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
            };

            var pcConfig = new PeerConnectionConfiguration();
            await pc1.InitializeAsync(pcConfig);

            await pc2.InitializeAsync(pcConfig);

            var ev1 = new ManualResetEventSlim(initialState: false);
            var ev2 = new ManualResetEventSlim(initialState: false);

            pc1.Connected += () => ev1.Set();
            pc2.Connected += () => ev2.Set();
            evExchangeCompleted.Reset();
            pc1.CreateOffer();
            ev1.Wait(millisecondsTimeout: 5000);
            ev2.Wait(millisecondsTimeout: 5000);
            evExchangeCompleted.Wait(millisecondsTimeout: 5000);
        }
Ejemplo n.º 3
0
        public async void PeerConnectionLocalConnect()
        {
            using (var pc1 = new PeerConnection())
            {
                await pc1.InitializeAsync();

                using (var pc2 = new PeerConnection())
                {
                    await pc2.InitializeAsync();

                    // Prepare SDP event handlers
                    pc1.LocalSdpReadytoSend += async(string type, string sdp) =>
                    {
                        await pc2.SetRemoteDescriptionAsync(type, sdp);

                        if (type == "offer")
                        {
                            pc2.CreateAnswer();
                        }
                    };
                    pc2.LocalSdpReadytoSend += async(string type, string sdp) =>
                    {
                        await pc1.SetRemoteDescriptionAsync(type, sdp);

                        if (type == "offer")
                        {
                            pc1.CreateAnswer();
                        }
                    };
                    pc1.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid)
                                                   => pc2.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                    pc2.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid)
                                                   => pc1.AddIceCandidate(sdpMid, sdpMlineindex, candidate);

                    // Connect
                    var conn1 = new ManualResetEventSlim(initialState: false);
                    var conn2 = new ManualResetEventSlim(initialState: false);
                    pc1.Connected += () => conn1.Set();
                    pc2.Connected += () => conn2.Set();
                    pc1.CreateOffer();
                    WaitForSdpExchangeCompleted(conn1, conn2);

                    pc1.Close();
                    pc2.Close();
                }
            }
        }
Ejemplo n.º 4
0
        public async void PeerConnectionLocalConnect()
        {
            using (var pc1 = new PeerConnection())
            {
                await pc1.InitializeAsync();

                using (var pc2 = new PeerConnection())
                {
                    await pc2.InitializeAsync();

                    // Prepare SDP event handlers
                    pc1.LocalSdpReadytoSend += async(SdpMessage message) =>
                    {
                        await pc2.SetRemoteDescriptionAsync(message);

                        if (message.Type == SdpMessageType.Offer)
                        {
                            pc2.CreateAnswer();
                        }
                    };
                    pc2.LocalSdpReadytoSend += async(SdpMessage message) =>
                    {
                        await pc1.SetRemoteDescriptionAsync(message);

                        if (message.Type == SdpMessageType.Offer)
                        {
                            pc1.CreateAnswer();
                        }
                    };
                    pc1.IceCandidateReadytoSend += (IceCandidate candidate) => pc2.AddIceCandidate(candidate);
                    pc2.IceCandidateReadytoSend += (IceCandidate candidate) => pc1.AddIceCandidate(candidate);

                    // Connect
                    var conn1 = new ManualResetEventSlim(initialState: false);
                    var conn2 = new ManualResetEventSlim(initialState: false);
                    pc1.Connected += () => conn1.Set();
                    pc2.Connected += () => conn2.Set();
                    pc1.CreateOffer();
                    WaitForSdpExchangeCompleted(conn1, conn2);

                    pc1.Close();
                    pc2.Close();
                }
            }
        }
        protected async Task MakeICECall(PeerConnection pc1, PeerConnection pc2)
        {
            pc1.LocalSdpReadytoSend += (string type, string sdp) =>
            {
                pc2.SetRemoteDescription(type, sdp);
                if (type == "offer")
                {
                    pc2.CreateAnswer();
                }
            };
            pc2.LocalSdpReadytoSend += (string type, string sdp) =>
            {
                pc1.SetRemoteDescription(type, sdp);
                if (type == "offer")
                {
                    pc1.CreateAnswer();
                }
            };
            pc1.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid) =>
            {
                pc2.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
            };
            pc2.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid) =>
            {
                pc1.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
            };

            var pcConfig = new PeerConnectionConfiguration();
            await pc1.InitializeAsync(pcConfig);

            await pc2.InitializeAsync(pcConfig);

            var ev1 = new ManualResetEventSlim(initialState: false);
            var ev2 = new ManualResetEventSlim(initialState: false);

            pc1.Connected += () => ev1.Set();
            pc2.Connected += () => ev2.Set();
            pc1.CreateOffer();
            ev1.Wait(millisecondsTimeout: 5000);
            ev2.Wait(millisecondsTimeout: 5000);
        }
Ejemplo n.º 6
0
        public async void PeerConnectionLocalConnect()
        {
            using (var pc1 = new PeerConnection())
            {
                await pc1.InitializeAsync();

                using (var pc2 = new PeerConnection())
                {
                    await pc2.InitializeAsync();

                    // Prepare SDP event handlers
                    var completed = new ManualResetEventSlim(initialState: false);
                    pc1.LocalSdpReadytoSend += async(SdpMessage message) =>
                    {
                        // Send caller offer to callee
                        await pc2.SetRemoteDescriptionAsync(message);

                        Assert.AreEqual(SdpMessageType.Offer, message.Type);
                        pc2.CreateAnswer();
                    };
                    pc2.LocalSdpReadytoSend += async(SdpMessage message) =>
                    {
                        // Send callee answer back to caller
                        await pc1.SetRemoteDescriptionAsync(message);

                        Assert.AreEqual(SdpMessageType.Answer, message.Type);
                        completed.Set();
                    };
                    pc1.IceCandidateReadytoSend += (IceCandidate candidate) => pc2.AddIceCandidate(candidate);
                    pc2.IceCandidateReadytoSend += (IceCandidate candidate) => pc1.AddIceCandidate(candidate);

                    // Connect
                    pc1.CreateOffer();
                    WaitForSdpExchangeCompleted(completed);

                    pc1.Close();
                    pc2.Close();
                }
            }
        }
        private async void DssSignaler_OnMessage(NodeDssSignaler.Message message)
        {
            Logger.Log($"DSS received message: {message.MessageType}");

            // Ensure that the filtering values are up to date before passing the message on.
            //UpdateCodecFilters();
            //_peerConnection.PreferredAudioCodec = PreferredAudioCodec;
            //_peerConnection.PreferredAudioCodecExtraParamsRemote = PreferredAudioCodecExtraParamsRemoteTextBox.Text;
            //_peerConnection.PreferredAudioCodecExtraParamsLocal = PreferredAudioCodecExtraParamsLocalTextBox.Text;
            //_peerConnection.PreferredVideoCodec = PreferredVideoCodec;
            //_peerConnection.PreferredVideoCodecExtraParamsRemote = PreferredVideoCodecExtraParamsRemoteTextBox.Text;
            //_peerConnection.PreferredVideoCodecExtraParamsLocal = PreferredVideoCodecExtraParamsLocalTextBox.Text;

            switch (message.MessageType)
            {
            case NodeDssSignaler.Message.WireMessageType.Offer:
                await ApplyRemoteOfferAsync(message.Data);

                // If we get an offer, we immediately send an answer back once the offer is applied
                _peerConnection.CreateAnswer();
                break;

            case NodeDssSignaler.Message.WireMessageType.Answer:
                await ApplyRemoteAnswerAsync(message.Data);

                break;

            case NodeDssSignaler.Message.WireMessageType.Ice:
                // TODO - This is NodeDSS-specific
                // this "parts" protocol is defined above, in OnIceCandidateReadyToSend listener
                var parts = message.Data.Split(new string[] { message.IceDataSeparator }, StringSplitOptions.RemoveEmptyEntries);
                // Note the inverted arguments; candidate is last here, but first in OnIceCandidateReadyToSend
                _peerConnection.AddIceCandidate(parts[2], int.Parse(parts[1]), parts[0]);
                break;

            default:
                throw new InvalidOperationException($"Unhandled signaler message type '{message.MessageType}'");
            }
        }
Ejemplo n.º 8
0
        private async void DssSignaler_OnMessage(NodeDssSignaler.Message message)
        {
            Logger.Log($"DSS received message: {message.MessageType}");

            // Ensure that the filtering values are up to date before passing the message on.
            //UpdateCodecFilters();
            //_peerConnection.PreferredAudioCodec = PreferredAudioCodec;
            //_peerConnection.PreferredAudioCodecExtraParamsRemote = PreferredAudioCodecExtraParamsRemoteTextBox.Text;
            //_peerConnection.PreferredAudioCodecExtraParamsLocal = PreferredAudioCodecExtraParamsLocalTextBox.Text;
            //_peerConnection.PreferredVideoCodec = PreferredVideoCodec;
            //_peerConnection.PreferredVideoCodecExtraParamsRemote = PreferredVideoCodecExtraParamsRemoteTextBox.Text;
            //_peerConnection.PreferredVideoCodecExtraParamsLocal = PreferredVideoCodecExtraParamsLocalTextBox.Text;

            switch (message.MessageType)
            {
            case NodeDssSignaler.Message.WireMessageType.Offer:
                await ApplyRemoteOfferAsync(message.Data);

                // If we get an offer, we immediately send an answer back once the offer is applied
                _peerConnection.CreateAnswer();
                break;

            case NodeDssSignaler.Message.WireMessageType.Answer:
                await ApplyRemoteAnswerAsync(message.Data);

                break;

            case NodeDssSignaler.Message.WireMessageType.Ice:
                // TODO - This is NodeDSS-specific
                _peerConnection.AddIceCandidate(message.ToIceCandidate());
                break;

            default:
                throw new InvalidOperationException($"Unhandled signaler message type '{message.MessageType}'");
            }
        }
Ejemplo n.º 9
0
 public void AddIceCandidate(IceCandidate candidate)
 {
     _peerConnection.AddIceCandidate(candidate.ToNative());
 }
Ejemplo n.º 10
0
        public async Task <string> InitiateCallRTC()
        {
            var list = new List <string>();

            list.Add(this.Configuration.GetSection("Key")["iceServer"]);
            AudioTrackSource microphoneSource = null;
            LocalAudioTrack  localAudioTrack  = null;
            Transceiver      audioTransceiver = null;

            var iceServer = new IceServer
            {
                Urls         = list,
                TurnPassword = this.Configuration.GetSection("Key")["turnPwd"],
                TurnUserName = this.Configuration.GetSection("Key")["turnUser"]
            };

            var serverList = new List <IceServer>();

            serverList.Add(iceServer);
            var connectionConfig = new PeerConnectionConfiguration {
                IceServers       = serverList,
                IceTransportType = IceTransportType.All,
                BundlePolicy     = BundlePolicy.Balanced,
                SdpSemantic      = SdpSemantic.UnifiedPlan
            };
            var connection = new PeerConnection();
            await connection.InitializeAsync(connectionConfig);

            microphoneSource = await DeviceAudioTrackSource.CreateAsync();

            var audioTrackConfig = new LocalAudioTrackInitConfig
            {
                trackName = "microphone_track"
            };

            localAudioTrack = LocalAudioTrack.CreateFromSource(microphoneSource, audioTrackConfig);

            audioTransceiver = connection.AddTransceiver(MediaKind.Audio);
            audioTransceiver.LocalAudioTrack  = localAudioTrack;
            audioTransceiver.DesiredDirection = Transceiver.Direction.SendReceive;

            var signaler = new NamedPipeSignaler.NamedPipeSignaler(connection, "testpipe");

            connection.Connected += () => {
                Console.WriteLine("PeerConnection: connected.");
            };

            signaler.SdpMessageReceived += async(SdpMessage message) =>
            {
                // Note: we use 'await' to ensure the remote description is applied
                // before calling CreateAnswer(). Failing to do so will prevent the
                // answer from being generated, and the connection from establishing.
                await connection.SetRemoteDescriptionAsync(message);

                if (message.Type == SdpMessageType.Offer)
                {
                    connection.CreateAnswer();
                }
            };

            await signaler.StartAsync();

            signaler.IceCandidateReceived += (IceCandidate candidate) => {
                connection.AddIceCandidate(candidate);
            };

            connection.IceStateChanged += (IceConnectionState newState) => {
                Console.WriteLine($"ICE state: {newState}");
            };

            if (signaler.IsClient)
            {
                Console.WriteLine("Connecting to remote peer...");
                connection.CreateOffer();
            }
            else
            {
                Console.WriteLine("Waiting for offer from remote peer...");
            }

            return(connection.IsConnected + "-" + connection.Name + "-");
        }
Ejemplo n.º 11
0
        static async Task Main(string[] args)
        {
            DataChannel dataChannel = null;

            try
            {
                // Create a new peer connection automatically disposed at the end of the program
                using var pc = new PeerConnection();

                // Initialize the connection with a STUN server to allow remote access
                var config = new PeerConnectionConfiguration
                {
                    IceServers = new List <IceServer> {
                        new IceServer {
                            Urls = { "stun:stun.l.google.com:19302" }
                        }
                    }
                };
                await pc.InitializeAsync(config);

                Console.WriteLine("Peer connection initialized.");

                Console.WriteLine("Opening data channel");
                dataChannel = await pc.AddDataChannelAsync("data", true, true);

                // Setup signaling
                Console.WriteLine("Starting signaling...");
                var signaler = new NamedPipeSignaler.NamedPipeSignaler(pc, "testpipe");
                signaler.SdpMessageReceived += (string type, string sdp) => {
                    pc.SetRemoteDescription(type, sdp);
                    if (type == "offer")
                    {
                        pc.CreateAnswer();
                    }
                };
                signaler.IceCandidateReceived += (string sdpMid, int sdpMlineindex, string candidate) => {
                    pc.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                };
                await signaler.StartAsync();

                // Start peer connection
                pc.Connected       += () => { Console.WriteLine("PeerConnection: connected."); };
                pc.IceStateChanged += (IceConnectionState newState) => { Console.WriteLine($"ICE state: {newState}"); };

                pc.DataChannelAdded += (DataChannel c) =>
                {
                    Console.WriteLine("DataChannel added");

                    c.MessageReceived += (byte[] _msg) =>
                    {
                        Console.WriteLine("received {0} bytes", _msg.Length);
                    };
                };

                if (signaler.IsClient)
                {
                    Console.WriteLine("Connecting to remote peer...");
                    pc.CreateOffer();
                }
                else
                {
                    Console.WriteLine("Waiting for offer from remote peer...");
                }

                Console.WriteLine("Press a 'S' to send data. 'Esc' to exit ...");

                ConsoleKeyInfo key;

                while ((key = Console.ReadKey(true)).Key != ConsoleKey.Escape)
                {
                    if (key.Key == ConsoleKey.S)
                    {
                        Console.WriteLine("Sending data");
                        dataChannel.SendMessage(new byte[3000]);
                    }
                }
                signaler.Stop();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Program termined.");
        }
Ejemplo n.º 12
0
        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            // Request access to microphone and camera
            var settings = new MediaCaptureInitializationSettings();

            settings.StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo;
            var capture = new MediaCapture();
            await capture.InitializeAsync(settings);

            // Retrieve a list of available video capture devices (webcams).
            List <VideoCaptureDevice> deviceList =
                await PeerConnection.GetVideoCaptureDevicesAsync();

            // Get the device list and, for example, print them to the debugger console
            foreach (var device in deviceList)
            {
                // This message will show up in the Output window of Visual Studio
                Debugger.Log(0, "", $"Webcam {device.name} (id: {device.id})\n");
            }

            _peerConnection = new PeerConnection();


            var config = new PeerConnectionConfiguration
            {
                IceServers = new List <IceServer> {
                    new IceServer {
                        Urls = { "stun:stun.l.google.com:19302" }
                    }
                }
            };
            await _peerConnection.InitializeAsync(config);

            Debugger.Log(0, "", "Peer connection initialized successfully.\n");

            await _peerConnection.AddLocalAudioTrackAsync();

            if (Settings.m_showLocal)
            {
                //LocalVideoTrack _localVideoTrack;
                await _peerConnection.AddLocalVideoTrackAsync();

                _peerConnection.I420LocalVideoFrameReady += Peer_LocalI420AFrameReady;
                await _peerConnection.AddLocalAudioTrackAsync();



                remoteVideoPlayerElement.Visibility = Visibility.Visible;
            }
            else
            {
                _peerConnection.Connected += () =>
                {
                    Debugger.Log(0, "", "PeerConnection: connected.\n");
                };
                _peerConnection.IceStateChanged += (IceConnectionState newState) =>
                {
                    Debugger.Log(0, "", $"ICE state: {newState}\n");
                };

                _peerConnection.I420RemoteVideoFrameReady += Peer_RemoteI420AFrameReady;

                _peerConnection.LocalSdpReadytoSend     += Peer_LocalSdpReadytoSend;
                _peerConnection.IceCandidateReadytoSend += Peer_IceCandidateReadytoSend;

                // Initialize the signaler
                _signaler = new NodeDssSignaler()
                {
                    HttpServerAddress = "http://10.44.160.22:3000/",
                    LocalPeerId       = "DINF-D60015-43A",
                    RemotePeerId      = "HOLOLENS-RO2J0",
                };
                _signaler.OnMessage += (NodeDssSignaler.Message msg) =>
                {
                    switch (msg.MessageType)
                    {
                    case NodeDssSignaler.Message.WireMessageType.Offer:
                        _peerConnection.SetRemoteDescription("offer", msg.Data);
                        _peerConnection.CreateAnswer();
                        break;

                    case NodeDssSignaler.Message.WireMessageType.Answer:
                        _peerConnection.SetRemoteDescription("answer", msg.Data);
                        break;

                    case NodeDssSignaler.Message.WireMessageType.Ice:
                        var parts = msg.Data.Split(new string[] { msg.IceDataSeparator },
                                                   StringSplitOptions.RemoveEmptyEntries);
                        // Note the inverted arguments for historical reasons.
                        // 'candidate' is last in AddIceCandidate(), but first in the message.
                        string sdpMid        = parts[2];
                        int    sdpMlineindex = int.Parse(parts[1]);
                        string candidate     = parts[0];
                        _peerConnection.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                        break;
                    }
                };

                _signaler.StartPollingAsync();
            }

            // Interactions
            Debug.WriteLine("[Playback::start] Waiting for a connection...");

            m_dsUdpSocket = new DatagramSocket();
            m_dsUdpSocket.MessageReceived += Socket_MessageReceived;

            // Initialization UDP communication
            try
            {
                await m_dsUdpSocket.ConnectAsync(new EndpointPair(new HostName(Settings.m_sIPLocalUDP), Settings.m_sPortLocalUDP, new HostName(Settings.m_sIPRemoteUDP), Settings.m_sPortRemoteUDP));

                m_output = new DataWriter(m_dsUdpSocket.OutputStream);
                Debug.WriteLine("[Playback::start] UDP connection initialization ok");
            }
            catch (Exception)
            {
                Debug.WriteLine("[Playback::start] Error - UDP connection initialization ");
            }
        }
Ejemplo n.º 13
0
        static async Task Main(string[] args)
        {
            try
            {
                bool needVideo = Array.Exists(args, arg => (arg == "-v") || (arg == "--video"));
                bool needAudio = Array.Exists(args, arg => (arg == "-a") || (arg == "--audio"));

                // Asynchronously retrieve a list of available video capture devices (webcams).
                var deviceList = await PeerConnection.GetVideoCaptureDevicesAsync();

                // For example, print them to the standard output
                foreach (var device in deviceList)
                {
                    Console.WriteLine($"Found webcam {device.name} (id: {device.id})");
                }

                // Create a new peer connection automatically disposed at the end of the program
                using var pc = new PeerConnection();

                // Initialize the connection with a STUN server to allow remote access
                var config = new PeerConnectionConfiguration
                {
                    IceServers = new List <IceServer> {
                        new IceServer {
                            Urls = { "stun:stun.l.google.com:19302" }
                        }
                    }
                };
                await pc.InitializeAsync(config);

                Console.WriteLine("Peer connection initialized.");

                // Record video from local webcam, and send to remote peer
                if (needVideo)
                {
                    Console.WriteLine("Opening local webcam...");
                    await pc.AddLocalVideoTrackAsync();
                }

                // Record audio from local microphone, and send to remote peer
                if (needAudio)
                {
                    Console.WriteLine("Opening local microphone...");
                    await pc.AddLocalAudioTrackAsync();
                }

                // Setup signaling
                Console.WriteLine("Starting signaling...");
                var signaler = new NamedPipeSignaler.NamedPipeSignaler(pc, "testpipe");
                signaler.SdpMessageReceived += (string type, string sdp) => {
                    pc.SetRemoteDescription(type, sdp);
                    if (type == "offer")
                    {
                        pc.CreateAnswer();
                    }
                };
                signaler.IceCandidateReceived += (string sdpMid, int sdpMlineindex, string candidate) => {
                    pc.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                };
                await signaler.StartAsync();

                // Start peer connection
                pc.Connected       += () => { Console.WriteLine("PeerConnection: connected."); };
                pc.IceStateChanged += (IceConnectionState newState) => { Console.WriteLine($"ICE state: {newState}"); };
                int numFrames = 0;
                pc.I420RemoteVideoFrameReady += (I420AVideoFrame frame) => {
                    ++numFrames;
                    if (numFrames % 60 == 0)
                    {
                        Console.WriteLine($"Received video frames: {numFrames}");
                    }
                };
                if (signaler.IsClient)
                {
                    Console.WriteLine("Connecting to remote peer...");
                    pc.CreateOffer();
                }
                else
                {
                    Console.WriteLine("Waiting for offer from remote peer...");
                }

                Console.WriteLine("Press a key to stop recording...");
                Console.ReadKey(true);

                signaler.Stop();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            Console.WriteLine("Program termined.");
        }
Ejemplo n.º 14
0
        private async void Window_Initialized(object sender, EventArgs e)
        {
            _peerConnection = new PeerConnection();
            var config = new PeerConnectionConfiguration
            {
                IceServers = new List <IceServer> {
                    new IceServer {
                        Urls = { "turn:35.193.0.31:3478" }, TurnPassword = "******", TurnUserName = "******"
                    }
                }
            };

            _peerConnection.Connected += () =>
            {
                Debugger.Log(0, "", "Peerconnection: DONE");
            };
            _peerConnection.IceStateChanged += (IceConnectionState newState) =>
            {
                Debugger.Log(0, "", $"ICE state: {newState}\n");
            };

            await _peerConnection.InitializeAsync(config);

            _dc = await _peerConnection.AddDataChannelAsync(14, "vzgo", true, true);

            Debugger.Log(0, "", "Peer connection initialized successfully.\n");

            _peerConnection.LocalSdpReadytoSend     += Peer_LocalSdpReadytoSendAsync;
            _peerConnection.IceCandidateReadytoSend += Peer_IceCandidateReadytoSend;
            _hubConnection = new HubConnectionBuilder()
                             .WithUrl(new Uri(SignallerConstants.SignallerUrl))
                             .AddJsonProtocol()
                             .WithAutomaticReconnect(new[] { TimeSpan.Zero, TimeSpan.Zero, TimeSpan.FromSeconds(10) })
                             .Build();


            _hubConnection.On <string>("Message", (message) =>
            {
                var msg = JsonConvert.DeserializeObject <SignallingMessage>(message);
                switch (msg.MessageType)
                {
                case SignallingMessage.WireMessageType.Offer:
                    _peerConnection.SetRemoteDescription("offer", msg.Data);
                    _peerConnection.CreateAnswer();
                    break;

                case SignallingMessage.WireMessageType.Answer:
                    _peerConnection.SetRemoteDescription("answer", msg.Data);
                    break;

                case SignallingMessage.WireMessageType.Ice:
                    var parts = msg.Data.Split(new string[] { msg.IceDataSeparator },
                                               StringSplitOptions.RemoveEmptyEntries);
                    // Note the inverted arguments for historical reasons.
                    // 'candidate' is last in AddIceCandidate(), but first in the message.
                    string sdpMid     = parts[2];
                    int sdpMlineindex = int.Parse(parts[1]);
                    string candidate  = parts[0];
                    _peerConnection.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                    break;
                }
            });

            await _hubConnection.StartAsync();

            await _hubConnection.InvokeAsync("JoinRoom", SignallerConstants.RoomName);
        }
Ejemplo n.º 15
0
    public async Task SetupAsync(Signaler signaler, bool isServer, uint clientNodeId = 0)
    {
        await pc.InitializeAsync(new PeerConnectionConfiguration {
            IceServers = new List <IceServer> {
                new IceServer {
                    Urls = { signaler.IceServerUrl }
                }
            }
        });

        var tcs = new TaskCompletionSource <bool>();

        // Do signaling
        //  https://microsoft.github.io/MixedReality-WebRTC/manual/cs/cs-signaling.html
        //  https://microsoft.github.io/MixedReality-WebRTC/manual/cs/helloworld-cs-signaling-core3.html

        pc.LocalSdpReadytoSend += (SdpMessage sdpMessage) => {
            // ここはawaitではなくWaitにしないとSocketが切れる.スレッドセーフ関係?
            signaler.SendSdpAsync(sdpMessage.Type == SdpMessageType.Offer, sdpMessage.Content, clientNodeId).Wait();
        };
        pc.IceCandidateReadytoSend += (IceCandidate candidate) => {
            signaler.SendIceAsync(candidate.SdpMid, candidate.SdpMlineIndex, candidate.Content, clientNodeId).Wait();
        };

        pc.IceStateChanged += (IceConnectionState state) => {
            Logger.Debug("Connection", $"ICE state changed to {state}");
            // https://microsoft.github.io/MixedReality-WebRTC/versions/release/2.0/api/Microsoft.MixedReality.WebRTC.IceConnectionState.html
            if (state == IceConnectionState.Connected)
            {
                Connected = true;
            }
            if (state == IceConnectionState.Closed || state == IceConnectionState.Disconnected || state == IceConnectionState.Failed)
            {
                Connected = false;
                OnDisconnect();
            }

            if (!isServer && state == IceConnectionState.Failed)
            {
                tcs.SetException(new ConnectionException("Failed to establish a WebRTC connection"));
            }
        };

        signaler.SdpReceived += async(bool isOffer, string sdp, uint cid) => {
            if (isServer && cid != clientNodeId)
            {
                // ignore messages for other clients
                return;
            }

            await pc.SetRemoteDescriptionAsync(new SdpMessage {
                Type    = isOffer ? SdpMessageType.Offer : SdpMessageType.Answer,
                Content = sdp
            });

            if (isOffer)
            {
                pc.CreateAnswer();
            }
        };
        signaler.IceReceived += (string sdpMid, int sdpMLineIndex, string candidate, uint cid) => {
            if (isServer && cid != clientNodeId)
            {
                // ignore messages for other clients
                return;
            }

            pc.AddIceCandidate(new IceCandidate {
                SdpMid        = sdpMid,
                SdpMlineIndex = sdpMLineIndex,
                Content       = candidate
            });
            //Logger.Write((isServer ? "Server: " : "Client: ") + $"{sdpMid} {sdpMLineIndex} {candidate}");
        };

        if (isServer)
        {
            TaskCompletionSource <DataChannel>[] completionSources = channelTypes.Select(
                _ => new TaskCompletionSource <DataChannel>()
                ).ToArray();

            pc.DataChannelAdded += (dc) => {
                foreach (var type in channelTypes)
                {
                    if (dc.Label == channelLabels[(int)type])
                    {
                        completionSources[(int)type].SetResult(dc);
                    }
                }
            };

            Logger.Debug("Connection", "Server is ready for signaling");
            await signaler.NotifyReadyAsync(clientNodeId);

            Logger.Debug("Connection", "Server: Waiting for DC");
            foreach (var type in channelTypes)
            {
                channels[(int)type] = await completionSources[(int)type].Task;
            }
        }
        else
        {
            // Define channels
            // Sync channel (unreliable)
            channels[(int)ChannelType.Sync] = await pc.AddDataChannelAsync(
                channelLabels[(int)ChannelType.Sync], ordered : false, reliable : false);

            // Message channel (reliable but order is not guaranteed)
            channels[(int)ChannelType.Control] = await pc.AddDataChannelAsync(
                channelLabels[(int)ChannelType.Control], ordered : false, reliable : true);

            // Blob channel (reliable and ordered)
            channels[(int)ChannelType.Blob] = await pc.AddDataChannelAsync(
                channelLabels[(int)ChannelType.Blob], ordered : true, reliable : true);

            // Audio channel (unreliable)
            channels[(int)ChannelType.Audio] = await pc.AddDataChannelAsync(
                channelLabels[(int)ChannelType.Audio], ordered : false, reliable : false);

            Logger.Debug("Connection", "Client: Waiting for server ready");
            await signaler.WaitReadyAsync();

            pc.CreateOffer();
        }

        foreach (var(dc, idx) in channels.Select((dc, idx) => (dc, idx)))
        {
            dc.MessageReceived += (data) => {
                threadChannels[idx].Writer.TryWrite(data);  // Always succeeds because the Channel is unbounded
            };
            dc.StateChanged += () => {
                Logger.Debug("Connection", $"DC {(ChannelType)idx} state changed to {dc.State}");
                if (dc.State == DataChannel.ChannelState.Closing)
                {
                    // Disconnect handling
                    Connected = false;
                }
            };
        }

        //await Task.Delay(5000);

        if (!isServer)
        {
            // FIXME: Waiting pc.Connected not work in server (cannot establish a connection to client)
            //        In server, should wait until all DataChannels are added?
            pc.Connected += () => {
                tcs.SetResult(true);
            };
            await tcs.Task;
        }
    }
Ejemplo n.º 16
0
        static private async Task StartStend()
        {
            var             autoEvent        = new AutoResetEvent(false);
            bool            video_translator = true;
            bool            file_created     = false;
            FileStream      file             = null;
            Quartus         quartus          = Quartus.GetInstance();
            Microcontroller arduino          = Microcontroller.Create();

            if (video_translator)
            {
                // Asynchronously retrieve a list of available video capture devices (webcams).
                var deviceList = await DeviceVideoTrackSource.GetCaptureDevicesAsync();


                // For example, print them to the standard output
                foreach (var device in deviceList)
                {
                    Console.WriteLine($"Found webcam {device.name} (id: {device.id})");
                }
            }

            // Create a new peer connection automatically disposed at the end of the program
            var pc = new PeerConnection();
            // Initialize the connection with a STUN server to allow remote access
            var config = SystemConfiguration.PeerConnectionSettings;


            await pc.InitializeAsync(config);

            Console.WriteLine("Peer connection initialized.");
            //var chen = await pc.AddDataChannelAsync("sendDataChannel", true, true, cancellationToken: default);
            Console.WriteLine("Opening local webcam...");


            // pc - PeerConnection object
            Transceiver                videoTransceiver = null;
            VideoTrackSource           videoTrackSource = null;
            LocalVideoTrack            localVideoTrack  = null;
            LocalVideoDeviceInitConfig c = new LocalVideoDeviceInitConfig();

            await VideoDeviceSelection();

            videoTrackSource = await Camera.CreateAsync(SystemConfiguration.VideoDeviceSettings);


            WebSocketSharp.WebSocket signaling = new WebSocketSharp.WebSocket(CreateSignalingServerUrl(), "id_token", "alpine");
            pc.LocalSdpReadytoSend += (SdpMessage message) =>
            {
                //Console.WriteLine(SdpMessage.TypeToString(message.Type));
                Console.WriteLine(message.Content);
                //Console.WriteLine(HttpUtility.JavaScriptStringEncode(message.Content));
                Console.WriteLine("Sdp offer to send: {\"data\":{\"description\":{\"type\":\"" + SdpMessage.TypeToString(message.Type) + "\",\"sdp\":\"" + HttpUtility.JavaScriptStringEncode(message.Content) + "\"}}}");
                signaling.Send(message.ToABJson());
            };

            pc.RenegotiationNeeded += () =>
            {
                Console.WriteLine("Regotiation needed");
                bool OfferCreated = pc.CreateOffer();
                Console.WriteLine("OfferCreated? {0}", OfferCreated);
            };
            pc.DataChannelAdded += (DataChannel channel) =>
            {
                Console.WriteLine("Added data channel ID: {0}, Label: {1}; Reliable: {2}, Ordered: {3}", channel.ID, channel.Label, channel.Reliable, channel.Ordered);

                if (channel.Label == "sendDataChannel")
                {
                    channel.MessageReceived += (byte[] mess) => {
                        try
                        {
                            CTP_packet command = JsonSerializer.Deserialize <CTP_packet>(mess);
                            Console.WriteLine(arduino.SendCTP_Command(command));
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    };
                }
                else
                {
                    if (file_created == false)
                    {
                        file         = new FileStream(channel.Label, FileMode.Append);
                        file_created = true;
                    }
                    channel.MessageReceived += async(byte[] mess) =>
                    {
                        // Console.WriteLine(System.Text.Encoding.Default.GetString(mess));
                        if (mess.Length == 3 && System.Text.Encoding.Default.GetString(mess) == "EOF")
                        {
                            string file_name = file.Name;
                            file.Close();
                            string t = await quartus.RunQuartusCommandAsync($"quartus_pgm -m jtag –o \"p;{file_name}@1\"");

                            File.Delete(file_name);
                            file_created = false;
                        }
                        else
                        {
                            WriteFileSegment(mess, file);
                        }
                    };
                }

                channel.StateChanged += () =>
                {
                    Console.WriteLine("State change: {0}", channel.State);
                };
            };

            pc.IceCandidateReadytoSend += (IceCandidate candidate) =>
            {
                //Console.WriteLine("Content: {0}, SdpMid: {1}, SdpMlineIndex: {2}", candidate.Content, candidate.SdpMid, candidate.SdpMlineIndex);
                try
                {
                    Console.WriteLine("Candidate to send: Content: {0}, SdpMid: {1}, SdpMlineIndex: {2}", candidate.Content, candidate.SdpMid, candidate.SdpMlineIndex);
                    signaling.Send(candidate.ToABJson());
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error to send local ice candidate");
                }
            };
            //videoTrackSource.I420AVideoFrameReady += (frame) =>
            //{
            //    Console.WriteLine("Argb32 frame ready. {0} : {1}", frame.width, frame.height);
            //    Console.WriteLine("DataA: {0}, DataU: {1}, DataV: {2}, DataY: {3}", Marshal.SizeOf(frame.dataA),
            //                        Marshal.SizeOf(frame.dataU),
            //                        Marshal.SizeOf(frame.dataV),
            //                        Marshal.SizeOf(frame.dataY));
            //};

            signaling.OnMessage += async(sender, message) =>
            {
                (string header, string correct_message) = message.Data.DivideHeaderAndOriginalJSON();
                Console.WriteLine("Correct message: {0}", correct_message);
                Console.WriteLine("Header: {0}", header);
                if (header == "{\"data\":{\"getRemoteMedia\":" && correct_message == "true")
                {
                    Console.WriteLine("Create local video track...");
                    var trackSettings = new LocalVideoTrackInitConfig {
                        trackName = "webcam_track"
                    };
                    localVideoTrack = LocalVideoTrack.CreateFromSource(videoTrackSource, new LocalVideoTrackInitConfig {
                        trackName = "webcam_track"
                    });
                    Console.WriteLine("Create video transceiver and add webcam track...");
                    TransceiverInitSettings option = new TransceiverInitSettings();
                    option.Name      = "webcam_track";
                    option.StreamIDs = new List <string> {
                        "webcam_name"
                    };
                    videoTransceiver = pc.AddTransceiver(MediaKind.Video, option);
                    videoTransceiver.DesiredDirection = Transceiver.Direction.SendOnly;
                    videoTransceiver.LocalVideoTrack  = localVideoTrack;

                    bool OfferCreated = pc.CreateOffer();
                    Console.WriteLine("OfferCreated? {0}", OfferCreated);
                }
                //Console.WriteLine(message.Data);
                if (header.IndexOf("candidate") != -1 && correct_message != "null")
                {
                    try
                    {
                        var candidate = JsonSerializer.Deserialize <ICEJavaScriptNotation>(correct_message);
                        Console.WriteLine("Content of ice: {0}, SdpMid: {1}, SdpMLineIndex: {2}", candidate.candidate, candidate.sdpMid, candidate.sdpMLineIndex);
                        pc.AddIceCandidate(candidate.ToMRNetCoreNotation());
                        Console.WriteLine("Deserialized by ice_candidate");
                        //return;
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Could not deserialize as ice candidate");
                    }
                }

                if (header.IndexOf("description") != -1)
                {
                    try
                    {
                        SdpMessage received_description = JsonSerializer.Deserialize <SDPJavaScriptNotation>(correct_message).ToMRNetCoreNotation();
                        await pc.SetRemoteDescriptionAsync(received_description);

                        if (received_description.Type == SdpMessageType.Offer)
                        {
                            bool res = pc.CreateAnswer();
                            Console.WriteLine("Answer created? {0}", res);
                        }
                        Console.WriteLine("Deserialized by sdp_message");
                    }
                    catch (Exception)
                    {
                        Console.WriteLine("Could not deserialize as sdp message");
                    }
                }
            };


            pc.Connected += () =>
            {
                Console.WriteLine("Connected");
            };
            pc.IceStateChanged += (IceConnectionState newState) =>
            {
                if (newState == IceConnectionState.Disconnected)
                {
                    Console.WriteLine("Disconected");
                }
            };


            signaling.Connect();
            if (!video_translator)
            {
                signaling.Send("{\"data\":{\"getRemoteMedia\":true}}");
            }

            //Console.WriteLine("Press a key to terminate the application...");
            Console.ReadKey(true);
            Console.WriteLine("Program termined.");
            file?.Close();
            pc?.Close();
            signaling?.Close();
            //arduino?.Close();
            //(var a, var b) = ConvertString("{\"data\":{\"candidate\":null}}");
            //Console.WriteLine("{0}, {1}", a, b);
        }
Ejemplo n.º 17
0
        //Loaded-EventHandler of ui: executes after ui-loading
        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            //Request access to mic and cam
            MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();

            settings.StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo;

            MediaCapture capture = new MediaCapture();
            await capture.InitializeAsync(settings);

            //Get list of cams
            camList = await PeerConnection.GetVideoCaptureDevicesAsync();

            //Print list to log
            foreach (var cam in camList)
            {
                Debugger.Log(0, "", $"Webcam: {cam.name} (id: {cam.id})\n");
            }

            //Ask user for ids (show MessageBox)
            await ShowIdInputBoxAsync();

            //New PeerConnection (Access to WebRTC)
            peerConnection = new PeerConnection();
            //Create PeerConnection-config
            PeerConnectionConfiguration config = new PeerConnectionConfiguration()
            {
                IceServers = new List <IceServer>()
                {
                    //Using google stun server for testing
                    new IceServer()
                    {
                        Urls = { "stun:stun.l.google.com:19302" }
                    }
                }
            };

            //Initialize PeerContection
            await peerConnection.InitializeAsync(config);

            //Event fires, when local video frame is captured and ready for rendering
            peerConnection.I420LocalVideoFrameReady += Peer_LocalI420FrameReady;
            //Event fires, when remote video frame is receved and ready for rendering
            peerConnection.I420RemoteVideoFrameReady += Peer_RemoteI420FrameReady;
            //Events fires, when SdpMessage is ready for sending
            peerConnection.LocalSdpReadytoSend += Peer_LocalSdpReadytoSend;
            //Event fires, when IceCandidate is ready for sending
            peerConnection.IceCandidateReadytoSend += Peer_IceCandidateReadytoSend;
            //Set DebuggingLog-messages
            peerConnection.Connected       += () => Debugger.Log(0, "", "PeerConnection: connected\n");
            peerConnection.IceStateChanged += (IceConnectionState newState) => Debugger.Log(0, "", $"ICE state: {newState}\n");

            Debugger.Log(0, "", "Peer conection initialized successfully\n");

            //Adds cam-tracks from standart (first) devices [add parameter to specify cam-device or -specifications]
            await peerConnection.AddLocalVideoTrackAsync(new PeerConnection.LocalVideoTrackSettings()
            {
                videoDevice = cam
            });

            //Same for mic [no specifications possible: always uses the first mic in list]
            await peerConnection.AddLocalAudioTrackAsync();

            //Initialize the signaler (Properties from MessageBox)
            signaler = new NodeDssSignaler()
            {
                HttpServerAddress = nodeDssServerIp,
                LocalPeerId       = localId,
                RemotePeerId      = remoteId
            };
            signaler.OnMessage += (NodeDssSignaler.Message msg) =>
            {
                switch (msg.MessageType)
                {
                case NodeDssSignaler.Message.WireMessageType.Offer:
                    peerConnection.SetRemoteDescription("offer", msg.Data);
                    peerConnection.CreateAnswer();
                    break;

                case NodeDssSignaler.Message.WireMessageType.Answer:
                    peerConnection.SetRemoteDescription("answer", msg.Data);
                    break;

                case NodeDssSignaler.Message.WireMessageType.Ice:
                    string[] parts = msg.Data.Split(new string[] { msg.IceDataSeparator }, StringSplitOptions.RemoveEmptyEntries);
                    //Changing order of parts
                    string sdpMid        = parts[2];
                    int    sdpMlineindex = int.Parse(parts[1]);
                    string candidate     = parts[0];
                    peerConnection.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                    break;
                }
            };
            signaler.StartPollingAsync();
        }
Ejemplo n.º 18
0
 public void AddIceCandidate(RTCIceCandidate iceCandidate)
 {
     MustNotDisposed();
     _peerConnectionImpl.AddIceCandidate(iceCandidate);
 }
Ejemplo n.º 19
0
        static async Task Main(string[] args)
        {
            Transceiver      audioTransceiver = null;
            Transceiver      videoTransceiver = null;
            AudioTrackSource audioTrackSource = null;
            VideoTrackSource videoTrackSource = null;
            LocalAudioTrack  localAudioTrack  = null;
            LocalVideoTrack  localVideoTrack  = null;

            try
            {
                bool needVideo = Array.Exists(args, arg => (arg == "-v") || (arg == "--video"));
                bool needAudio = Array.Exists(args, arg => (arg == "-a") || (arg == "--audio"));

                // Asynchronously retrieve a list of available video capture devices (webcams).
                var deviceList = await PeerConnection.GetVideoCaptureDevicesAsync();

                // For example, print them to the standard output
                foreach (var device in deviceList)
                {
                    Console.WriteLine($"Found webcam {device.name} (id: {device.id})");
                }

                // Create a new peer connection automatically disposed at the end of the program
                using var pc = new PeerConnection();

                // Initialize the connection with a STUN server to allow remote access
                var config = new PeerConnectionConfiguration
                {
                    IceServers = new List <IceServer> {
                        new IceServer {
                            Urls = { "stun:stun.l.google.com:19302" }
                        }
                    }
                };
                await pc.InitializeAsync(config);

                Console.WriteLine("Peer connection initialized.");

                // Record video from local webcam, and send to remote peer
                if (needVideo)
                {
                    Console.WriteLine("Opening local webcam...");
                    videoTrackSource = await DeviceVideoTrackSource.CreateAsync();

                    Console.WriteLine("Create local video track...");
                    var trackSettings = new LocalVideoTrackInitConfig {
                        trackName = "webcam_track"
                    };
                    localVideoTrack = LocalVideoTrack.CreateFromSource(videoTrackSource, trackSettings);

                    Console.WriteLine("Create video transceiver and add webcam track...");
                    videoTransceiver = pc.AddTransceiver(MediaKind.Video);
                    videoTransceiver.DesiredDirection = Transceiver.Direction.SendReceive;
                    videoTransceiver.LocalVideoTrack  = localVideoTrack;
                }

                // Record audio from local microphone, and send to remote peer
                if (needAudio)
                {
                    Console.WriteLine("Opening local microphone...");
                    audioTrackSource = await DeviceAudioTrackSource.CreateAsync();

                    Console.WriteLine("Create local audio track...");
                    var trackSettings = new LocalAudioTrackInitConfig {
                        trackName = "mic_track"
                    };
                    localAudioTrack = LocalAudioTrack.CreateFromSource(audioTrackSource, trackSettings);

                    Console.WriteLine("Create audio transceiver and add mic track...");
                    audioTransceiver = pc.AddTransceiver(MediaKind.Audio);
                    audioTransceiver.DesiredDirection = Transceiver.Direction.SendReceive;
                    audioTransceiver.LocalAudioTrack  = localAudioTrack;
                }

                // Setup signaling
                Console.WriteLine("Starting signaling...");
                var signaler = new NamedPipeSignaler.NamedPipeSignaler(pc, "testpipe");
                signaler.SdpMessageReceived += async(SdpMessage message) =>
                {
                    await pc.SetRemoteDescriptionAsync(message);

                    if (message.Type == SdpMessageType.Offer)
                    {
                        pc.CreateAnswer();
                    }
                };
                signaler.IceCandidateReceived += (IceCandidate candidate) =>
                {
                    pc.AddIceCandidate(candidate);
                };
                await signaler.StartAsync();

                // Start peer connection
                pc.Connected       += () => { Console.WriteLine("PeerConnection: connected."); };
                pc.IceStateChanged += (IceConnectionState newState) => { Console.WriteLine($"ICE state: {newState}"); };
                int numFrames = 0;
                pc.VideoTrackAdded += (RemoteVideoTrack track) =>
                {
                    track.I420AVideoFrameReady += (I420AVideoFrame frame) =>
                    {
                        ++numFrames;
                        if (numFrames % 60 == 0)
                        {
                            Console.WriteLine($"Received video frames: {numFrames}");
                        }
                    };
                };
                if (signaler.IsClient)
                {
                    Console.WriteLine("Connecting to remote peer...");
                    pc.CreateOffer();
                }
                else
                {
                    Console.WriteLine("Waiting for offer from remote peer...");
                }

                Console.WriteLine("Press a key to stop recording...");
                Console.ReadKey(true);

                signaler.Stop();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            localAudioTrack?.Dispose();
            localVideoTrack?.Dispose();

            Console.WriteLine("Program termined.");

            localAudioTrack.Dispose();
            localVideoTrack.Dispose();
            audioTrackSource.Dispose();
            videoTrackSource.Dispose();
        }
Ejemplo n.º 20
0
        protected override async void OnMessage(MessageEventArgs e)
        {
            var msg     = e.Data;
            var jsonMsg = JObject.Parse(msg);

            Util.WriteLine($"WebSocketSignaller.OnMessage {Util.PrettyPrint(msg, 20)}...");

            if ((string)jsonMsg["type"] == "ice")
            {
                while (!peer.Initialized)
                {
                    // This delay is needed due to an initialise bug in the Microsoft.MixedReality.WebRTC
                    // nuget packages up to version 0.2.3. On master awaiting pc.InitializeAsync does end
                    // up with the pc object being ready.
                    Util.WriteLine("WebSocketSignaller.peer.NotInitialized - Sleeping for 1s while peer connection is initialising...");
                    await Task.Delay(1000);
                }

                Util.WriteLine("WebSocketSignaller.AddIceCandidate");
                peer.AddIceCandidate((string)jsonMsg["sdpMLineindex"], (int)jsonMsg["sdpMid"], (string)jsonMsg["candidate"]);
            }
            else if ((string)jsonMsg["type"] == "sdp")
            {
                Util.WriteLine("WebSocketSignaller.OnMessage - Received SDP offer.");

                peer.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid) =>
                {
                    var iceCandidate = new JObject {
                        { "type", "ice" },
                        { "candidate", candidate },
                        { "sdpMLineindex", sdpMlineindex },
                        { "sdpMid", sdpMid }
                    }.ToString();

                    Util.WriteLine($"WebSocketSignaller.SendIceCandidate - {Util.PrettyPrint(iceCandidate, 20)}");
                    Context.WebSocket.Send(iceCandidate);
                };

                peer.LocalSdpReadytoSend += (string type, string sdp) =>
                {
                    var msgType   = receivedOffer ? "answer" : "offer";
                    var sdpAnswer = new JObject {
                        { "type", "sdp" },
                        { msgType, sdp }
                    }.ToString();

                    Util.WriteLine($"WebSocketSignaller.SendSDP - {Util.PrettyPrint(sdpAnswer, 20)}");
                    Context.WebSocket.Send(sdpAnswer);
                };

                if (!peer.Initialized)
                {
                    Util.WriteLine($"WebSocketSignaller.peer.InitializeAsync");
                    await peer.InitializeAsync(PeerConnectionConfig.Default);
                }

                if (jsonMsg.ContainsKey("answer"))
                {
                    var answer = (string)jsonMsg["answer"];
                    Util.WriteLine($"WebSocketSignaller.SetRemoteDescription - answer='{Util.PrettyPrint(answer, 20)}...'");
                    await peer.SetRemoteDescriptionAsync("answer", answer);
                }
                else if (jsonMsg.ContainsKey("offer"))
                {
                    var offer = (string)jsonMsg["offer"];
                    Util.WriteLine($"WebSocketSignaller.SetRemoteDescription - offer='{Util.PrettyPrint(offer, 20)}...'");
                    await peer.SetRemoteDescriptionAsync("offer", offer);

                    receivedOffer = true;

                    Util.WriteLine($"WebSocketSignaller.CreateAnswer");
                    if (!peer.CreateAnswer())
                    {
                        Console.WriteLine("WebSocketSignaller - Failed to create peer connection answer, closing peer connection.");
                        Dispose();
                    }
                }
                else
                {
                    throw new Exception("Unknown message " + msg);
                }

                Util.WriteLine("WebSocketSignaller.Complete");
            }
        }
Ejemplo n.º 21
0
        public async Task InBand()
        {
            // Setup
            var config = new PeerConnectionConfiguration();
            var pc1    = new PeerConnection();
            var pc2    = new PeerConnection();
            await pc1.InitializeAsync(config);

            await pc2.InitializeAsync(config);

            pc1.LocalSdpReadytoSend += (string type, string sdp) =>
            {
                pc2.SetRemoteDescription(type, sdp);
                if (type == "offer")
                {
                    pc2.CreateAnswer();
                }
            };
            pc2.LocalSdpReadytoSend += (string type, string sdp) =>
            {
                pc1.SetRemoteDescription(type, sdp);
                if (type == "offer")
                {
                    pc1.CreateAnswer();
                }
            };
            pc1.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid)
                                           => pc2.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
            pc2.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid)
                                           => pc1.AddIceCandidate(sdpMid, sdpMlineindex, candidate);

            // Add dummy out-of-band data channel to force SCTP negotiating.
            // Otherwise after connecting AddDataChannelAsync() will fail.
            await pc1.AddDataChannelAsync(42, "dummy", false, false);

            await pc2.AddDataChannelAsync(42, "dummy", false, false);

            // Connect
            {
                var c1 = new ManualResetEventSlim(false);
                var c2 = new ManualResetEventSlim(false);
                pc1.Connected += () => c1.Set();
                pc2.Connected += () => c2.Set();
                Assert.True(pc1.CreateOffer());
                Assert.True(c1.Wait(TimeSpan.FromSeconds(60.0)));
                Assert.True(c2.Wait(TimeSpan.FromSeconds(60.0)));
                Assert.True(pc1.IsConnected);
                Assert.True(pc1.IsConnected);
            }

            // Negotiate data channel in-band
            DataChannel data1 = null;
            DataChannel data2 = null;

            {
                var c2 = new ManualResetEventSlim(false);
                pc2.DataChannelAdded += (DataChannel channel) =>
                {
                    data2 = channel;
                    c2.Set();
                };
                data1 = await pc1.AddDataChannelAsync("test_data_channel", true, true);

                Assert.IsNotNull(data1);
                Assert.True(c2.Wait(TimeSpan.FromSeconds(60.0)));
                Assert.IsNotNull(data2);
                Assert.AreEqual(data1.Label, data2.Label);
                // Do not test DataChannel.ID; at this point for in-band channels the ID has not
                // been agreed upon with the remote peer yet.
            }

            // Send data
            {
                var    c2       = new ManualResetEventSlim(false);
                string sentText = "Some sample text";
                byte[] msg      = Encoding.UTF8.GetBytes(sentText);
                data2.MessageReceived += (byte[] _msg) =>
                {
                    var receivedText = Encoding.UTF8.GetString(_msg);
                    Assert.AreEqual(sentText, receivedText);
                    c2.Set();
                };
                data1.SendMessage(msg);
                Assert.True(c2.Wait(TimeSpan.FromSeconds(60.0)));
            }

            // Clean-up
            pc1.Close();
            pc1.Dispose();
            pc2.Close();
            pc2.Dispose();
        }
Ejemplo n.º 22
0
 public void AddIceCandidate(Core.IceCandidate iceCandidate) => _peerConnection.AddIceCandidate(iceCandidate.ToPlatformNative());
Ejemplo n.º 23
0
 private void OnIceCandidateReadytoSend2(string candidate, int sdpMlineindex, string sdpMid)
 {
     pc1_.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
 }
Ejemplo n.º 24
0
 private void OnIceCandidateReadytoSend2(IceCandidate candidate)
 {
     pc1_.AddIceCandidate(candidate);
 }