예제 #1
0
        public async Task CreateTurnClient()
        {
            var turnUri = new Uri(
                Environment.GetEnvironmentVariable(
                    FactOnlyTurnAvailableAttribute.TurnUrlVarName));
            var userInfo = turnUri.UserInfo.Split(':');
            await Assert.ThrowsAsync <ArgumentException>(
                async() =>
            {
                await IceServer.CreateTurnClient(
                    new[] { new IceServer(new[] { "stun://stun.l.google.com:19302" }) }
                    );
            }
                );

            var servers = new List <IceServer>()
            {
                new IceServer(new[] { "turn://turn.does-not-exists.org" }),
            };

            await Assert.ThrowsAsync <IceServerException>(
                async() => { await IceServer.CreateTurnClient(servers); });

            servers.Add(new IceServer(new[] { turnUri }, userInfo[0], userInfo[1]));
            var turnClient = await IceServer.CreateTurnClient(servers);

            Assert.Equal(userInfo[0], turnClient.Username);
            Assert.Equal(userInfo[1], turnClient.Password);
        }
예제 #2
0
        public IceServerViewModel(IceServer iceServer)
        {
            IceServer = iceServer;

            Url      = iceServer.Url;
            Username = iceServer.Username;
            Password = iceServer.Password;
        }
예제 #3
0
        public static void AddDefaultIceServersList(WebRtcAdapter.Call.Call call)
        {
            if (_localSettings.DeserializeIceServersList() == null ||
                !(_localSettings.DeserializeIceServersList()).Any())
            {
                List <IceServer> iceServersList = new List <IceServer>();

                ObservableCollection <IceServerModel> iceServerModelList = new ObservableCollection <IceServerModel>();

                foreach (IceServer iceServer in AddDefaultIceServers)
                {
                    IceServerModel iceServerModel = new IceServerModel();
                    iceServerModel.Urls       = iceServer.Urls;
                    iceServerModel.Username   = iceServer.Username;
                    iceServerModel.Credential = iceServer.Credential;

                    iceServerModelList.Add(iceServerModel);
                }

                _localSettings.SerializeIceServersList(iceServerModelList);

                foreach (var ice in iceServerModelList)
                {
                    IceServer iceServer = new IceServer();
                    iceServer.Urls       = ice.Urls;
                    iceServer.Username   = ice.Username;
                    iceServer.Credential = ice.Credential;

                    iceServersList.Add(iceServer);
                }

                call.AddIceServers(iceServersList);
                call.SetIceServers(iceServersList);
            }
            else
            {
                List <IceServer> iceServersList = new List <IceServer>();

                ObservableCollection <IceServerModel> iceServerModelList = _localSettings.DeserializeIceServersList();

                foreach (var ice in iceServerModelList)
                {
                    IceServer iceServer = new IceServer();
                    iceServer.Urls       = ice.Urls;
                    iceServer.Username   = ice.Username;
                    iceServer.Credential = ice.Credential;

                    iceServersList.Add(iceServer);
                }

                call.AddIceServers(iceServersList);
                call.SetIceServers(iceServersList);
            }
        }
            /// <summary>
            /// Factory method used to create a new IceServer object.
            /// </summary>
            /// <param name="uri">The uri of the ice server.</param>
            /// <param name="userName">The username to log into the ice server.</param>
            /// <param name="password">The password to log into the ice server.</param>
            /// <returns>An ice candidate object with the given handle.</returns>
            public static IceServer Create(string uri, string userName = null, string password = null)
            {
                IceServer iceServer = new IceServer()
                {
                    Uri      = uri,
                    UserName = userName,
                    Password = password,
                };

                return(iceServer);
            }
        public IceServerViewModel(IceServer iceServer)
        {
            if (iceServer == null)
            {
                throw new ArgumentNullException();
            }
            IceServer = iceServer;

            Url      = iceServer.Url;
            Username = iceServer.Username;
            Password = iceServer.Password;
        }
        public static PeerConnection.IceServer ToNative(this IceServer self)
        {
            var builder = PeerConnection.IceServer.InvokeBuilder(self.Urls)
                          .SetTlsCertPolicy(self.TlsCertPolicy.ToNative());

            if (!string.IsNullOrEmpty(self.Username))
            {
                builder.SetUsername(self.Username)
                .SetPassword(self.Password);
            }

            return(builder.CreateIceServer());
        }
예제 #7
0
        private static IEnumerable <IceServer> LoadFromConfigAllTURN()
        {
            Regex turn_regex = new Regex(@"[T,t][u, U][r, R][n, N]");

            // Adding all turn servers. To use turn servers you should
            // add to WebRTC_Remote_FPGA_stand.dll.config
            // TurnPassword and UserName
            return(ConfigurationManager.AppSettings.AllKeys.Where((key) => turn_regex.IsMatch(key)).Select((key) => {
                IceServer turnServer = new IceServer();
                string Value = ConfigurationManager.AppSettings.Get(key);
                turnServer.Urls.Add(ReadTurnParametr(Value, "Url"));
                turnServer.TurnUserName = ReadTurnParametr(Value, "UserName");
                turnServer.TurnPassword = ReadTurnParametr(Value, "Password");
                return turnServer;
            }));
        }
예제 #8
0
        public async Task CreateTurnClient()
        {
            var turnUri  = FactOnlyTurnAvailableAttribute.GetTurnUri();
            var userInfo = turnUri.UserInfo.Split(':');
            await Assert.ThrowsAsync <ArgumentException>(
                async() =>
            {
                await IceServer.CreateTurnClient(
                    new[] { new IceServer(new[] { "stun://stun.l.google.com:19302" }) }
                    );
            }
                );

            var servers = new List <IceServer>()
            {
                new IceServer(new[] { "turn://turn.does-not-exists.org" }),
            };

            await Assert.ThrowsAsync <IceServerException>(
                async() => { await IceServer.CreateTurnClient(servers); });

            servers.Add(new IceServer(new[] { turnUri }, userInfo[0], userInfo[1]));
            for (int i = 3; i > 0; i--)
            {
                TurnClient turnClient;
                try
                {
                    turnClient = await IceServer.CreateTurnClient(servers);
                }
                catch (IceServerException)
                {
                    // Try up to 3 times, as the servers are not well operational.
                    if (i > 1)
                    {
                        await Task.Delay(1000);

                        continue;
                    }

                    throw;
                }

                Assert.Equal(userInfo[0], turnClient.Username);
                Assert.Equal(userInfo[1], turnClient.Password);
            }
        }
 public static bool IsCompatible(this ScanTestScenario scenario, IceServer iceServer)
 {
     if (scenario == ScanTestScenario.Stun)
     {
         return(iceServer.IsStun);
     }
     if (scenario == ScanTestScenario.TurnUdp)
     {
         return(iceServer.IsTurn && iceServer.IsUdp);
     }
     if (scenario == ScanTestScenario.TurnTcp)
     {
         return(iceServer.IsTurn && iceServer.IsTcp && !iceServer.IsSecure);
     }
     if (scenario == ScanTestScenario.Turns)
     {
         return(iceServer.IsTurn && iceServer.IsTcp && iceServer.IsSecure);
     }
     return(false);
 }
예제 #10
0
        public static IReadOnlyList <IceServer> GetIceServers()
        {
            var list = new IceServer[_iceServers.Length];

            Array.Copy(_iceServers, list, list.Length);

            // Fisher–Yates shuffle
            int n = list.Length;

            while (n > 1)
            {
                n--;
                int       k     = _random.Next(n + 1);
                IceServer value = list[k];
                list[k] = list[n];
                list[n] = value;
            }

            return(list);
        }
        public static PeerConnectionConfiguration GetPeerConnectionConfiguration(CommunicationRelayConfiguration relayConfiguration)
        {
            IReadOnlyList <CommunicationIceServer> iceServers = (IReadOnlyList <CommunicationIceServer>)relayConfiguration.IceServers;
            var webRTCIceServers = new List <IceServer>();

            foreach (CommunicationIceServer iceServer in iceServers)
            {
                var webRTCIceServer = new IceServer();

                webRTCIceServer.Urls         = (List <string>)iceServer.Urls;
                webRTCIceServer.TurnUserName = iceServer.Username;
                webRTCIceServer.TurnPassword = iceServer.Credential;

                webRTCIceServers.Add(webRTCIceServer);
            }

            PeerConnectionConfiguration configuration = new PeerConnectionConfiguration();

            configuration.IceServers = webRTCIceServers;
            return(configuration);
        }
예제 #12
0
        private void AddDefaultIceServersList()
        {
            if (_localSettings.DeserializeIceServersList() == null ||
                !(_localSettings.DeserializeIceServersList()).Any())
            {
                ObservableCollection <IceServerModel> iceServersList = new ObservableCollection <IceServerModel>();

                foreach (IceServer iceServer in DefaultSettings.AddDefaultIceServers)
                {
                    IceServerModel iceServerModel = new IceServerModel();
                    iceServerModel.Urls       = iceServer.Urls;
                    iceServerModel.Username   = iceServer.Username;
                    iceServerModel.Credential = iceServer.Credential;

                    iceServersList.Add(iceServerModel);
                }

                _localSettings.SerializeIceServersList(iceServersList);
            }
            else
            {
                List <IceServer> iceServersList = new List <IceServer>();

                ObservableCollection <IceServerModel> list = _localSettings.DeserializeIceServersList();

                foreach (var ice in list)
                {
                    IceServer iceServer = new IceServer();
                    iceServer.Urls       = ice.Urls;
                    iceServer.Username   = ice.Username;
                    iceServer.Credential = ice.Credential;

                    iceServersList.Add(iceServer);
                }

                _call.AddIceServers(iceServersList);
                _call.SetIceServers(iceServersList);
            }
        }
예제 #13
0
        public MainWindow()
        {
            InitializeComponent();
            messages = new List <string>();
            textBoxServerArgs.Text            = "SimpleMessenger: default -h localhost -p 5050 -t 5000";
            buttonStartServer.IsEnabled       = true;
            buttonStopServer.IsEnabled        = false;
            buttonRestartServer.IsEnabled     = false;
            textBoxClientArgs.Text            = "SimpleMessenger: default -h localhost -p 5050 -t 2000";
            buttonStartClient.IsEnabled       = true;
            buttonIdleClient.IsEnabled        = false;
            buttonStopClient.IsEnabled        = false;
            buttonRestartClient.IsEnabled     = false;
            textBoxServerRestartInterval.Text = "1000";
            textBoxClientRestartInterval.Text = "1000";
            textBoxContentSize.Text           = "2";
            checkBoxAsync.IsChecked           = false;
            buttonClearLogs.IsEnabled         = false;
            buttonExportLogs.IsEnabled        = false;
            textBoxContentSize.IsEnabled      = false;
            iceServer = new IceServer();
            iceClient = new IceClient();
            iceServer.OnStatusChanged    += IceServer_OnStatusChanged;
            iceServer.OnMethodInvoked    += IceServer_OnMethodInvoked;
            iceServer.OnExceptionOccured += IceServer_OnExceptionOccured;
            iceClient.OnStatusChanged    += IceClient_OnStatusChanged;
            iceClient.OnMethodInvoked    += IceClient_OnMethodInvoked;
            iceClient.OnExceptionOccured += IceClient_OnExceptionOccured;
            IceServer_OnStatusChanged(iceServer.Status);
            IceClient_OnStatusChanged(iceClient.Status);

            if (App.IsNewInstance)
            {
                groupServer.Visibility = Visibility.Hidden;
                Title += " [Client ONLY]";
            }
        }
예제 #14
0
 private void BtnRestartServer_Click(object sender, RoutedEventArgs e)
 {
     buttonRestartServer.IsEnabled = false;
     buttonStartServer.IsEnabled   = false;
     buttonStopServer.IsEnabled    = false;
     AddMessage("User Restart Server: " + serverArgs);
     Task.Run(delegate
     {
         iceServer.OnStatusChanged    -= IceServer_OnStatusChanged;
         iceServer.OnExceptionOccured -= IceServer_OnExceptionOccured;
         iceServer.OnMethodInvoked    -= IceServer_OnMethodInvoked;
         iceServer.Exit();
         Thread.Sleep(serverRestartIntervalMS);
         iceServer = new IceServer();
         iceServer.OnStatusChanged    += IceServer_OnStatusChanged;
         iceServer.OnExceptionOccured += IceServer_OnExceptionOccured;
         iceServer.OnMethodInvoked    += IceServer_OnMethodInvoked;
         Application.Current.Dispatcher.Invoke(delegate
         {
             buttonStopServer.IsEnabled    = true;
             buttonRestartServer.IsEnabled = true;
         });
         var acmClose     = Bundle.ACMCloseFlag.CloseOff;
         var acmHeartbeat = Bundle.ACMHeartbeatFlag.HeartbeatOff;
         App.Current.Dispatcher.Invoke(() =>
         {
             Enum.TryParse("Close" + cbServerClose.Text, out acmClose);
             Enum.TryParse("Heartbeat" + cbServerHeartbeat.Text, out acmHeartbeat);
         });
         Thread.Sleep(1);
         Task.Run(() =>
         {
             iceServer.Start(serverArgs, acmClose, acmHeartbeat);
         });
     });
 }
예제 #15
0
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Logger    log    = Logger.Instance;
            IceServer server = new IceServer();

            server.StartServer();

            try
            {
                ClientController ctrl = new ClientController(server);

                Application.Run(new MainForm(ctrl));
            }
            catch (Exception ex)
            {
                log.Error("Failed to start the program: " + ex.ToString());
            }

            server.StopServer();
            log.Close();
        }
예제 #16
0
 public void RemoveIceServer(IceServer server)
 {
     _iceServersList.Remove(server);
 }
예제 #17
0
 public void AddIceServer(IceServer server)
 {
     _iceServersList.Add(server);
 }
예제 #18
0
        async Task LoadSettings()
        {
            // Default values:
            var configTraceServerIp = new ValidableNonEmptyString("127.0.0.1");

            StorageFile configFile = await StorageFile.GetFileFromApplicationUriAsync(
                new Uri(_configFilePath))
                                     .AsTask()
                                     .ConfigureAwait(false);

            string content = await FileIO.ReadTextAsync(configFile)
                             .AsTask()
                             .ConfigureAwait(false);

            JsonValue json = JsonValue.Parse(content);

            // Parses server info.
            _server = json.GetObject().GetNamedString("server");
            int startId = 0;

            if (_server.StartsWith("http://"))
            {
                startId = 7;
            }
            else if (_server.StartsWith("https://"))
            {
                startId = 8;

                // TODO: Supports SSL
            }

            _server = _server.Substring(startId);
            _port   = new ValidableIntegerString(
                (int)json.GetObject().GetNamedNumber("port"), 0, 65535);

            _heartbeat = new ValidableIntegerString(
                (int)json.GetObject().GetNamedNumber("heartbeat"), 0, 65535);

            var configIceServers = new ObservableCollection <IceServer>();

            // Parses turn server.
            if (json.GetObject().ContainsKey("turnServer"))
            {
                JsonValue turnServer = json.GetObject().GetNamedValue("turnServer");
                string    uri        = turnServer.GetObject().GetNamedString("uri");
                IceServer iceServer  = new IceServer(
                    uri.Substring(uri.IndexOf("turn:") + 5),
                    IceServer.ServerType.TURN);

                iceServer.Credential = turnServer.GetObject().GetNamedString("username");
                iceServer.Username   = turnServer.GetObject().GetNamedString("password");
                configIceServers.Add(iceServer);
            }

            // Parses stun server.
            if (json.GetObject().ContainsKey("stunServer"))
            {
                JsonValue stunServer = json.GetObject().GetNamedValue("stunServer");
                string    uri        = stunServer.GetObject().GetNamedString("uri");
                IceServer iceServer  = new IceServer(
                    uri.Substring(uri.IndexOf("stun:") + 5),
                    IceServer.ServerType.STUN);

                iceServer.Credential = stunServer.GetObject().GetNamedString("username");
                iceServer.Username   = stunServer.GetObject().GetNamedString("password");
                configIceServers.Add(iceServer);
            }

            // Default ones.
            configIceServers.Add(new IceServer("stun.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun1.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun2.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun3.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun4.l.google.com:19302", IceServer.ServerType.STUN));

            Conductor.Instance.ConfigureIceServers(configIceServers);
            var ntpServerAddress = new ValidableNonEmptyString("time.windows.com");

            RunOnUiThread(() =>
            {
                IceServers = configIceServers;
                NtpServer  = ntpServerAddress;
                NtpServer  = ntpServerAddress;
                Port       = _port;
                Ip         = new ValidableNonEmptyString(_server);
                HeartBeat  = _heartbeat;
                ReevaluateHasServer();
            });

            Conductor.Instance.ConfigureIceServers(configIceServers);
        }
예제 #19
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 + "-");
        }
예제 #20
0
        async Task LoadSettings()
        {
            // Default values:
            var configTraceServerIp = new ValidableNonEmptyString("127.0.0.1");

            StorageFile configFile = await StorageFile.GetFileFromApplicationUriAsync(
                new Uri(_configFilePath))
                                     .AsTask()
                                     .ConfigureAwait(false);

            string content = await FileIO.ReadTextAsync(configFile)
                             .AsTask()
                             .ConfigureAwait(false);

            JsonValue json = JsonValue.Parse(content);

            // Parses server info.
            var server = json.GetObject().GetNamedString("server");

            var parsed = new Uri(server);

            // if we don't have an explicit port in server, and we do have a port value
            if (parsed.IsDefaultPort && json.GetObject().ContainsKey("port"))
            {
                // use that port value in place of the default port
                var b = new UriBuilder(parsed);
                b.Port = (int)json.GetObject().GetNamedNumber("port");
                parsed = b.Uri;
            }

            // down-convert back to a string
            this.Uri = new ValidableNonEmptyString(parsed.ToString());

            HeartBeat = new ValidableIntegerString(
                (int)json.GetObject().GetNamedNumber("heartbeat"), 0, 65535);

            // parse auth
            if (json.GetObject().ContainsKey("authentication"))
            {
                var authNode = json.GetObject().GetNamedObject("authentication").GetObject();

                AuthCodeUri = authNode.ContainsKey("codeUri") ? authNode.GetNamedString("codeUri") : null;
                AuthPollUri = authNode.ContainsKey("pollUri") ? authNode.GetNamedString("pollUri") : null;
            }

            var configIceServers = new ObservableCollection <IceServer>();

            // Parses turn server.
            if (json.GetObject().ContainsKey("turnServer"))
            {
                JsonValue turnServer = json.GetObject().GetNamedValue("turnServer");
                string    uri        = turnServer.GetObject().GetNamedString("uri");
                IceServer iceServer  = new IceServer(
                    uri.Substring(uri.IndexOf("turn:") + 5),
                    IceServer.ServerType.TURN);

                if (turnServer.GetObject().ContainsKey("provider"))
                {
                    // if we do this, we need to ensure we set the username and credential
                    // in the future - we'll do this in ConnectToServer() by wiring up
                    // an event to the Conductor.TurnClient
                    TempTurnUri = turnServer.GetObject().GetNamedString("provider");
                }
                else
                {
                    iceServer.Username   = turnServer.GetObject().GetNamedString("username");
                    iceServer.Credential = turnServer.GetObject().GetNamedString("password");
                }

                configIceServers.Add(iceServer);
            }

            // Parses stun server.
            if (json.GetObject().ContainsKey("stunServer"))
            {
                JsonValue stunServer = json.GetObject().GetNamedValue("stunServer");
                string    uri        = stunServer.GetObject().GetNamedString("uri");
                IceServer iceServer  = new IceServer(
                    uri.Substring(uri.IndexOf("stun:") + 5),
                    IceServer.ServerType.STUN);

                iceServer.Username   = stunServer.GetObject().GetNamedString("username");
                iceServer.Credential = stunServer.GetObject().GetNamedString("password");
                configIceServers.Add(iceServer);
            }

            // Default ones.
            configIceServers.Add(new IceServer("stun.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun1.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun2.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun3.l.google.com:19302", IceServer.ServerType.STUN));
            configIceServers.Add(new IceServer("stun4.l.google.com:19302", IceServer.ServerType.STUN));

            Conductor.Instance.ConfigureIceServers(configIceServers);
            var ntpServerAddress = new ValidableNonEmptyString("time.windows.com");

            RunOnUiThread(() =>
            {
                IceServers = configIceServers;
                NtpServer  = ntpServerAddress;
                NtpServer  = ntpServerAddress;
                ReevaluateHasServer();
            });

            Conductor.Instance.ConfigureIceServers(configIceServers);
        }
예제 #21
0
        public void Initialize()
        {
            WebRTC.Initialize(_uiDispatcher);
            Conductor.Instance.ETWStatsEnabled = false;

            Cameras             = new ObservableCollection <MediaDevice>();
            Microphones         = new ObservableCollection <MediaDevice>();
            AudioPlayoutDevices = new ObservableCollection <MediaDevice>();

            // WebRTCUWP M58 library does not support audio capture/playout devices
            //foreach (MediaDevice audioCaptureDevice in Conductor.Instance.Media.GetAudioCaptureDevices())
            //{
            //    Microphones.Add(audioCaptureDevice);
            //}

            //foreach (MediaDevice audioPlayoutDevice in Conductor.Instance.Media.GetAudioPlayoutDevices())
            //{
            //    AudioPlayoutDevices.Add(audioPlayoutDevice);
            //}

            // HACK Remove Automatic Device Assignment
            if (SelectedCamera == null && Cameras.Count > 0)
            {
                SelectedCamera = Cameras.First();
            }

            if (SelectedMicrophone == null && Microphones.Count > 0)
            {
                SelectedMicrophone = Microphones.First();
            }

            Debug.WriteLine("Device Status: SelectedCamera: {0} - SelectedMic: {1}", SelectedCamera == null ? "NULL" : "OK", SelectedMicrophone == null ? "NULL" : "OK");
            if (SelectedAudioPlayoutDevice == null && AudioPlayoutDevices.Count > 0)
            {
                SelectedAudioPlayoutDevice = AudioPlayoutDevices.First();
            }

            Conductor.Instance.Media.OnMediaDevicesChanged += OnMediaDevicesChanged;
            Conductor.Instance.Signaller.OnPeerConnected   += (peerId, peerName) =>
            {
                RunOnUiThread(() =>
                {
                    if (Peers == null)
                    {
                        Peers = new ObservableCollection <Peer>();
                        Conductor.Instance.Peers = Peers;
                    }

                    Peers.Add(new Peer {
                        Id = peerId, Name = peerName
                    });
                });
            };

            Conductor.Instance.Signaller.OnPeerDisconnected += peerId =>
            {
                RunOnUiThread(() =>
                {
                    var peerToRemove = Peers?.FirstOrDefault(p => p.Id == peerId);
                    if (peerToRemove != null)
                    {
                        Peers.Remove(peerToRemove);
                    }
                });
            };

            Conductor.Instance.Signaller.OnSignedIn += () =>
            {
                RunOnUiThread(() =>
                {
                    IsConnected         = true;
                    IsMicrophoneEnabled = false;
                    IsCameraEnabled     = false;
                    IsConnecting        = false;

                    OnStatusMessageUpdate?.Invoke("Signed-In");
                });
            };

            Conductor.Instance.Signaller.OnServerConnectionFailure += (Exception ex) =>
            {
                RunOnUiThread(() =>
                {
                    IsConnecting = false;
                    OnStatusMessageUpdate?.Invoke("Server Connection Failure: " + ex.Message + "\n" + ex.StackTrace);
                });
            };

            Conductor.Instance.Signaller.OnDisconnected += () =>
            {
                RunOnUiThread(() =>
                {
                    IsConnected         = false;
                    IsMicrophoneEnabled = false;
                    IsCameraEnabled     = false;
                    IsDisconnecting     = false;
                    Peers?.Clear();
                    OnStatusMessageUpdate?.Invoke("Disconnected");
                });
            };

            Conductor.Instance.Signaller.OnMessageFromPeer += (id, message) =>
            {
                RunOnUiThread(() =>
                {
                    // TODO: Handles All Peer Messages (Signal Channel)
                });
            };

            Conductor.Instance.Signaller.OnPeerConnected += (id, name) =>
            {
                RunOnUiThread(() =>
                {
                    SelectedPeer = Peers.First(x => x.Id == id);
                    OnStatusMessageUpdate?.Invoke(string.Format("Connected Peer: {0}-{1}", SelectedPeer.Id, SelectedPeer.Name));
                });
            };

            // TODO: Restore Event Handler in Utility Wrapper
            // Implemented in Unity Consumer due to Event Handling Issue
            // Conductor.Instance.OnAddRemoteStream += Conductor_OnAddRemoteStream does not propagate

            Conductor.Instance.OnRemoveRemoteStream    += Conductor_OnRemoveRemoteStream;
            Conductor.Instance.OnAddLocalStream        += Conductor_OnAddLocalStream;
            Conductor.Instance.OnConnectionHealthStats += Conductor_OnPeerConnectionHealthStats;
            Conductor.Instance.OnPeerConnectionCreated += () =>
            {
                RunOnUiThread(() =>
                {
                    IsReadyToConnect    = false;
                    IsConnectedToPeer   = true;
                    IsReadyToDisconnect = false;
                    IsMicrophoneEnabled = false;
                    OnStatusMessageUpdate?.Invoke("Peer Connection Created");
                });
            };

            Conductor.Instance.OnPeerConnectionClosed += () =>
            {
                RunOnUiThread(() =>
                {
                    IsConnectedToPeer   = false;
                    _peerVideoTrack     = null;
                    _selfVideoTrack     = null;
                    IsMicrophoneEnabled = false;
                    IsCameraEnabled     = false;

                    // TODO: Clean-up References
                    //GC.Collect(); // Ensure all references are truly dropped.

                    OnStatusMessageUpdate?.Invoke("Peer Connection Closed");
                });
            };

            Conductor.Instance.OnPeerMessageDataReceived += (peerId, message) =>
            {
                OnPeerMessageDataReceived?.Invoke(peerId, message);
            };

            // DATA Channel Setup
            Conductor.Instance.OnPeerMessageDataReceived += (i, s) =>
            {
            };

            Conductor.Instance.OnReadyToConnect += () => { RunOnUiThread(() => { IsReadyToConnect = true; }); };

            IceServers   = new ObservableCollection <IceServer>();
            NewIceServer = new IceServer();
            AudioCodecs  = new ObservableCollection <CodecInfo>();
            var audioCodecList = WebRTC.GetAudioCodecs();

            string[] incompatibleAudioCodecs = new string[] { "CN32000", "CN16000", "CN8000", "red8000", "telephone-event8000" };
            VideoCodecs = new ObservableCollection <CodecInfo>();

            // TODO: REMOVE DISPLAY LIST SUPPORT
            var videoCodecList = WebRTC.GetVideoCodecs().OrderBy(codec =>
            {
                switch (codec.Name)
                {
                case "VP8": return(1);

                case "VP9": return(2);

                case "H264": return(3);

                default: return(99);
                }
            });

            RunOnUiThread(() =>
            {
                foreach (var audioCodec in audioCodecList)
                {
                    if (!incompatibleAudioCodecs.Contains(audioCodec.Name + audioCodec.ClockRate))
                    {
                        AudioCodecs.Add(audioCodec);
                    }
                }

                if (AudioCodecs.Count > 0)
                {
                    SelectedAudioCodec = AudioCodecs.FirstOrDefault(x => x.Name.Contains("PCMU"));
                }

                foreach (var videoCodec in videoCodecList)
                {
                    VideoCodecs.Add(videoCodec);
                }

                if (VideoCodecs.Count > 0)
                {
                    SelectedVideoCodec = VideoCodecs.FirstOrDefault(x => x.Name.Contains("H264"));
                }
            });

            RunOnUiThread(() =>
            {
                OnInitialized?.Invoke();
            });
        }
예제 #22
0
 public ClientController(IceServer server)
 {
     this.server = server;
     this.server.ClientsChangedCallback = ClientsListChanged;
 }
 public static RTCIceServer ToNative(this IceServer self)
 {
     return(new RTCIceServer(self.Urls, self.Username, self.Password, self.TlsCertPolicy.ToNative()));
 }
예제 #24
0
        async Task LoadSettings()
        {
            StorageFile configFile = await StorageFile.GetFileFromApplicationUriAsync(
                new Uri("ms-appx:///webrtcConfig.json"));

            string content = await FileIO.ReadTextAsync(configFile);

            JsonValue json = JsonValue.Parse(content);

            // Parses server info.
            _server = json.GetObject().GetNamedString("server");
            int startId = 0;

            if (_server.StartsWith("http://"))
            {
                startId = 7;
            }
            else if (_server.StartsWith("https://"))
            {
                startId = 8;

                // TODO: Supports SSL
            }

            _server    = _server.Substring(startId);
            _port      = json.GetObject().GetNamedNumber("port").ToString();
            _heartbeat = json.GetObject().GetNamedNumber("heartbeat").ToString();
            var  configIceServers     = new ObservableCollection <IceServer>();
            bool useDefaultIceServers = true;

            if (useDefaultIceServers)
            {
                // Clears all values.
                configIceServers.Clear();

                // Parses turn server.
                if (json.GetObject().ContainsKey("turnServer"))
                {
                    JsonValue turnServer = json.GetObject().GetNamedValue("turnServer");
                    string    uri        = turnServer.GetObject().GetNamedString("uri");
                    IceServer iceServer  = new IceServer(
                        uri.Substring(uri.IndexOf("turn:") + 5),
                        IceServer.ServerType.TURN);

                    iceServer.Credential = turnServer.GetObject().GetNamedString("username");
                    iceServer.Username   = turnServer.GetObject().GetNamedString("password");
                    configIceServers.Add(iceServer);
                }

                // Parses stun server.
                if (json.GetObject().ContainsKey("stunServer"))
                {
                    JsonValue stunServer = json.GetObject().GetNamedValue("stunServer");
                    string    uri        = stunServer.GetObject().GetNamedString("uri");
                    IceServer iceServer  = new IceServer(
                        uri.Substring(uri.IndexOf("stun:") + 5),
                        IceServer.ServerType.STUN);

                    iceServer.Credential = stunServer.GetObject().GetNamedString("username");
                    iceServer.Username   = stunServer.GetObject().GetNamedString("password");
                    configIceServers.Add(iceServer);
                }

                // Default ones.
                configIceServers.Add(new IceServer("stun.l.google.com:19302", IceServer.ServerType.STUN));
                configIceServers.Add(new IceServer("stun1.l.google.com:19302", IceServer.ServerType.STUN));
                configIceServers.Add(new IceServer("stun2.l.google.com:19302", IceServer.ServerType.STUN));
                configIceServers.Add(new IceServer("stun3.l.google.com:19302", IceServer.ServerType.STUN));
                configIceServers.Add(new IceServer("stun4.l.google.com:19302", IceServer.ServerType.STUN));
            }

            Conductor.Instance.ConfigureIceServers(configIceServers);
        }