Exemplo n.º 1
0
        public async Task BeforeConnect()
        {
            // Add local video track channel to #1
            var             settings = new PeerConnection.LocalVideoTrackSettings();
            LocalVideoTrack track1   = await pc1_.AddLocalVideoTrackAsync(settings);

            Assert.NotNull(track1);
            Assert.AreEqual(pc1_, track1.PeerConnection);

            // Wait for local SDP re-negotiation on #1.
            // This will not create an offer, since we're not connected yet.
            Assert.True(renegotiationEvent1_.Wait(TimeSpan.FromSeconds(60.0)));

            // Connect
            Assert.True(pc1_.CreateOffer());
            WaitForSdpExchangeCompleted();
            Assert.True(pc1_.IsConnected);
            Assert.True(pc2_.IsConnected);

            // Remove the track from #1
            renegotiationEvent1_.Reset();
            pc1_.RemoveLocalVideoTrack(track1);
            Assert.IsNull(track1.PeerConnection);
            track1.Dispose();

            // Wait for local SDP re-negotiation on #1
            Assert.True(renegotiationEvent1_.Wait(TimeSpan.FromSeconds(60.0)));

            // Confirm remote track was removed from #2
            Assert.True(trackRemovedEvent2_.Wait(TimeSpan.FromSeconds(60.0)));

            // Wait until SDP renegotiation finished
            WaitForSdpExchangeCompleted();
        }
        private void StartLocalVideoClicked(object sender, RoutedEventArgs e)
        {
            // Toggle between start and stop local video feed
            //< TODO dssStatsTimer.IsEnabled used for toggle, but dssStatsTimer should be
            // used also for remote statistics display (so even when no local video active)
            if (dssStatsTimer.IsEnabled)
            {
                StopLocalVideo();
                dssStatsTimer.Stop();
                localLoadText.Text      = "Load: -";
                localPresentText.Text   = "Present: -";
                localSkipText.Text      = "Skip: -";
                localLateText.Text      = "Late: -";
                remoteLoadText.Text     = "Load: -";
                remotePresentText.Text  = "Present: -";
                remoteSkipText.Text     = "Skip: -";
                remoteLateText.Text     = "Late: -";
                startLocalVideo.Content = "Start local video";
            }
            else
            {
                LogMessage("Opening local A/V stream...");

                // TODO - HACK: support multi-webcams locally for testing
                //_peerConnection.HACK_VideoDeviceIndex = HACK_GetVideoDeviceIndex();

                var uiThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                _peerConnection.AddLocalAudioTrackAsync().ContinueWith(addAudioTask =>
                {
                    // Continue on worker thread here
                    if (addAudioTask.Exception != null)
                    {
                        LogMessage(addAudioTask.Exception.Message);
                        return;
                    }

                    _peerConnection.AddLocalVideoTrackAsync().ContinueWith(addVideoTask =>
                    {
                        // Continue inside UI thread here
                        if (addVideoTask.Exception != null)
                        {
                            LogMessage(addVideoTask.Exception.Message);
                            return;
                        }
                        dssStatsTimer.Interval = TimeSpan.FromSeconds(1.0);
                        dssStatsTimer.Start();
                        startLocalVideo.Content = "Stop local video";
                        var idx = HACK_GetVideoDeviceIndex();                                    //< HACK
                        localPeerUidTextBox.Text  = GetDeviceUniqueIdLikeUnity((byte)idx);       //< HACK
                        remotePeerUidTextBox.Text = GetDeviceUniqueIdLikeUnity((byte)(1 - idx)); //< HACK
                        localVideoSourceName.Text = $"({VideoCaptureDevices[idx].DisplayName})"; //< HACK
                        localVideo.MediaPlayer.Play();
                        lock (_isLocalVideoPlayingLock)
                        {
                            _isLocalVideoPlaying = true;
                        }
                    }, uiThreadScheduler);
                });
            }
        }
Exemplo n.º 3
0
        static async Task Main()
        {
            try
            {
                Console.WriteLine("Starting...");

                ClientWebSocket         ws  = new ClientWebSocket();
                CancellationTokenSource cts = new CancellationTokenSource();

                // Set up the peer connection.
                var pc = new PeerConnection();

                pc.LocalSdpReadytoSend += async(string type, string sdp) =>
                {
                    Console.WriteLine($"Local SDP ready {type}");
                    //Console.WriteLine(sdp);

                    // Send out SDP offer to the remote peer.
                    await ws.SendAsync(Encoding.UTF8.GetBytes(sdp), WebSocketMessageType.Text, true, cts.Token);
                };

                var config = new PeerConnectionConfiguration();
                await pc.InitializeAsync(config);

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

                await pc.AddLocalAudioTrackAsync();

                await pc.AddLocalVideoTrackAsync(new PeerConnection.LocalVideoTrackSettings());

                await ws.ConnectAsync(new Uri(WEBSOCKET_SERVER_URI), cts.Token);

                pc.CreateOffer();

                // Wait for the SDP answer to arrive from the remote peer.
                byte[] answerSdpBuffer = new byte[8192];
                var    recvRes         = await ws.ReceiveAsync(answerSdpBuffer, cts.Token);

                string answerSdp = Encoding.UTF8.GetString(answerSdpBuffer, 0, recvRes.Count);

                //Console.WriteLine($"answer sdp: {answerSdp}");

                pc.SetRemoteDescription("answer", answerSdp);

                // Don't need the web socket anymore.
                await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, null, cts.Token);

                Console.WriteLine("Press any key to exit...");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
Exemplo n.º 4
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 ");
            }
        }
Exemplo n.º 5
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.");
        }
        //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();
        }