// ===============================
        // Public Method
        // ===============================

/// <summary>
/// IceServerのリストをRTCIceServerのリストに変換する
/// </summary>
/// <returns></returns>
        #if NETFX_CORE
        public Task <List <RTCIceServer> > ConvertIceServersToRTCIceServers()
        {
            var task = Task.Run(() =>
            {
                List <RTCIceServer> result = new List <RTCIceServer>();
                foreach (IceServer iceServer in IceServers)
                {
                    string url = "stun:";
                    if (iceServer.Type == IceServer.ServerType.TURN)
                    {
                        url = "turn:";
                    }
                    RTCIceServer server = null;
                    url   += iceServer.Host;
                    server = new RTCIceServer {
                        Url = url
                    };
                    if (iceServer.Credential != null)
                    {
                        server.Credential = iceServer.Credential;
                    }
                    if (iceServer.Username != null)
                    {
                        server.Username = iceServer.Username;
                    }
                    result.Add(server);
                }
                return(result);
            });

            return(task);
        }
Exemplo n.º 2
0
    void AddServer(string url, string username = null, string password = null)
    {
        // Store the ICE server as a stringified JSON object in option.value.
        GameObject option       = Instantiate(optionElement, optionParent);
        Text       optionText   = option.GetComponentInChildren <Text>();
        Button     optionButton = option.GetComponentInChildren <Button>();

        RTCIceServer iceServer = new RTCIceServer
        {
            urls       = new[] { url },
            username   = usernameInputField.text,
            credential = passwordInputField.text
        };

        optionText.text = url;

        if (!string.IsNullOrEmpty(username) || !string.IsNullOrEmpty(password))
        {
            optionText.text += $"[{username}:{password}]";
        }
        optionButton.onClick.AddListener(() => OnSelectServer(option));
        iceServers.Add(option, iceServer);

        urlInputField.text      = string.Empty;
        usernameInputField.text = string.Empty;
        passwordInputField.text = string.Empty;
    }
Exemplo n.º 3
0
 public static Webrtc.PeerConnection.IceServer ToNative(this RTCIceServer iceServer) =>
 Webrtc.PeerConnection.IceServer.InvokeBuilder(iceServer.Urls.ToList())
 //.SetTlsCertPolicy(iceServer.CredentialType?.ToNative() ??
 //Webrtc.PeerConnection.TlsCertPolicy.TlsCertPolicySecure)
 //.If(iceServer.Username != null, builder => builder.SetUsername(iceServer.Username))
 //.If(iceServer.Credential != null, builder => builder.SetPassword(iceServer.Credential))
 .CreateIceServer();
Exemplo n.º 4
0
 public static Webrtc.RTCIceServer ToNative(this RTCIceServer iceServer) =>
 new Webrtc.RTCIceServer
 (
     urlStrings: iceServer.Urls,
     username: iceServer.Username,
     credential: iceServer.Credential,
     tlsCertPolicy: iceServer.CredentialType?.ToNative() ?? Webrtc.RTCTlsCertPolicy.Secure
 );
Exemplo n.º 5
0
    //ピアの作成をする
    void CreatePeer()
    {
        //ローカル
        RTCConfiguration pc_config = new RTCConfiguration();
        var server = new RTCIceServer();

        server.urls          = new string[] { "stun:stun.webrtc.ecl.ntt.com:3478" };
        pc_config.iceServers = new RTCIceServer[] {
            server
        };
        localConnection = new RTCPeerConnection(ref pc_config);
        //データチャネルの作成
        RTCDataChannelInit conf = new RTCDataChannelInit(true);

        localDataChannel         = localConnection.CreateDataChannel("send", ref conf);
        localDataChannel.OnOpen  = new DelegateOnOpen(() => { Debug.Log("データチャネル:localOpen"); });
        localDataChannel.OnClose = new DelegateOnClose(() => { Debug.Log("データチャネル:localClose"); });
        //メディアストリームの追加(現在のバージョンだとメディアストリームは1つまでらしい)
        if (_rtcType == RTCTYPE.OFFER)
        {
            _videoStream = _streamCamera.CaptureStream(800, 450);
        }

        localConnection.OnDataChannel = new DelegateOnDataChannel(x => {
            Debug.Log("ondatachannel");
            remoteDataChannel           = x;
            remoteDataChannel.OnMessage = onDataChannelMessage;
        });
        localConnection.OnTrack = new DelegateOnTrack(x => {
            x.Track;
            //PlayVideo(x.Track);
        });
        localConnection.OnIceConnectionChange =
            new DelegateOnIceConnectionChange(state => { OnIceConnectionChange(localConnection, state); });

        //ICEの登録
        localConnection.OnIceCandidate = new DelegateOnIceCandidate(candidate => {
            if (!string.IsNullOrEmpty(candidate.candidate))
            {
                _localIceCandidate.Add(candidate);
                Debug.Log("アイス:add my Ice" + candidate.candidate);
            }
            else
            {
                Debug.Log("end ice candidate");
            }
        });

        Debug.Log("crete peer");
    }
Exemplo n.º 6
0
        public void AddIceServers(List <IceServer> iceServersList)
        {
            List <string> urlsList = new List <string>();

            foreach (IceServer ice in iceServersList)
            {
                foreach (string url in ice.Urls)
                {
                    string checkedUrl = string.Empty;

                    if (url.StartsWith("stun"))
                    {
                        checkedUrl = url;
                        if (!url.StartsWith("stun:"))
                        {
                            checkedUrl = $"stun:{url}";
                        }
                    }
                    if (url.StartsWith("turn"))
                    {
                        checkedUrl = url;
                        if (!url.StartsWith("turn:"))
                        {
                            checkedUrl = $"turn:{url}";
                        }
                    }
                    urlsList.Add(checkedUrl);
                }

                RTCIceServer server = new RTCIceServer {
                    Urls = urlsList
                };

                if (ice.Username != null)
                {
                    server.Username = ice.Username;
                }
                if (ice.Credential != null)
                {
                    server.Credential = ice.Credential;
                }

                _iceServers.Add(server);
            }
        }
Exemplo n.º 7
0
        public static Webrtc.PeerConnection.IceServer ToNative(this RTCIceServer iceServer)
        {
            var nativeIceServerBuilder = Webrtc.PeerConnection.IceServer.InvokeBuilder(iceServer.Urls.ToList());

            if (iceServer.CredentialType.HasValue)
            {
                nativeIceServerBuilder.SetTlsCertPolicy(iceServer.CredentialType?.ToNative());
            }
            if (iceServer.Username is not null)
            {
                nativeIceServerBuilder.SetUsername(iceServer.Username);
            }
            if (iceServer.Credential is not null)
            {
                nativeIceServerBuilder.SetPassword(iceServer.Credential);
            }
            var nativeIceServer = nativeIceServerBuilder.CreateIceServer();

            return(nativeIceServer);
        }
Exemplo n.º 8
0
        RTCConfiguration GetSelectedSdpSemantics()
        {
            RTCConfiguration config = default;
            var rtcIceServers       = new List <RTCIceServer>();

            foreach (var iceServer in this.m_signaling.m_acceptMessage.iceServers)
            {
                RTCIceServer rtcIceServer = new RTCIceServer();
                rtcIceServer.urls           = iceServer.urls.ToArray();
                rtcIceServer.username       = iceServer.username;
                rtcIceServer.credential     = iceServer.credential;
                rtcIceServer.credentialType = RTCIceCredentialType.OAuth;

                rtcIceServers.Add(rtcIceServer);
            }

            config.iceServers = rtcIceServers.ToArray();

            return(config);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Receives a new list of Ice servers and updates the local list of servers.
        /// </summary>
        /// <param name="iceServers">List of Ice servers to configure.</param>
        public void ConfigureIceServers(Collection <IceServer> iceServers)
        {
            _iceServers.Clear();
            foreach (IceServer iceServer in iceServers)
            {
                //Url format: stun:stun.l.google.com:19302
                string url = "stun:";
                if (iceServer.Type == IceServer.ServerType.TURN)
                {
                    url = "turn:";
                }

                RTCIceServer server = null;
                url += iceServer.Host.Value;
#if ORTCLIB
                //url += iceServer.Host.Value;
                server = new RTCIceServer()
                {
                    Urls = new List <string>(),
                };
                server.Urls.Add(url);
#else
                //url += iceServer.Host.Value + ":" + iceServer.Port.Value;
                server = new RTCIceServer {
                    Url = url
                };
#endif
                if (iceServer.Credential != null)
                {
                    server.Credential = iceServer.Credential;
                }

                if (iceServer.Username != null)
                {
                    server.Username = iceServer.Username;
                }

                _iceServers.Add(server);
            }
        }
Exemplo n.º 10
0
    //ピアの作成をする
    void CreatePeer()
    {
        //ローカル
        RTCConfiguration pc_config = new RTCConfiguration();
        var server = new RTCIceServer();

        server.urls          = new string[] { "stun:stun.webrtc.ecl.ntt.com:3478" };
        pc_config.iceServers = new RTCIceServer[] {
            server
        };
        localConnection = new RTCPeerConnection(ref pc_config);
        RTCDataChannelInit conf = new RTCDataChannelInit(true);

        localDataChannel         = localConnection.CreateDataChannel("send", ref conf);
        localDataChannel.OnOpen  = new DelegateOnOpen(() => { Debug.Log("データチャネル:localOpen"); });
        localDataChannel.OnClose = new DelegateOnClose(() => { Debug.Log("データチャネル:localClose"); });
        //localDataChannel.OnMessage = onDataChannelMessage;
        localConnection.OnDataChannel = new DelegateOnDataChannel(x => {
            Debug.Log("ondatachannel");
            remoteDataChannel           = x;
            remoteDataChannel.OnMessage = onDataChannelMessage;
        });
        localConnection.OnIceConnectionChange =
            new DelegateOnIceConnectionChange(state => { OnIceConnectionChange(localConnection, state); });

        //ICEの登録
        localConnection.OnIceCandidate = new DelegateOnIceCandidate(candidate => {
            if (!string.IsNullOrEmpty(candidate.candidate))
            {
                _localIceCandidate.Add(candidate);
                Debug.Log("アイス:add my Ice" + candidate.candidate);
            }
            else
            {
                Debug.Log("end ice candidate");
            }
        });

        Debug.Log("crete peer");
    }
Exemplo n.º 11
0
        private static Task <RTCPeerConnection> Createpc(WebSocketContext context, RTCIceServer stunServer, bool relayOnly)
        {
            if (_peerConnection != null)
            {
                _peerConnection.Close("normal");
            }

            List <RTCCertificate> presetCertificates = null;

            if (File.Exists(LOCALHOST_CERTIFICATE_PATH))
            {
                var localhostCert = new X509Certificate2(LOCALHOST_CERTIFICATE_PATH, (string)null, X509KeyStorageFlags.Exportable);
                presetCertificates = new List <RTCCertificate> {
                    new RTCCertificate {
                        Certificate = localhostCert
                    }
                };
            }

            RTCConfiguration pcConfiguration = new RTCConfiguration
            {
                //certificates = presetCertificates,
                //X_RemoteSignallingAddress = (context != null) ? context.UserEndPoint.Address : null,
                iceServers = stunServer != null ? new List <RTCIceServer> {
                    stunServer
                } : null,
                iceTransportPolicy = relayOnly ? RTCIceTransportPolicy.relay : RTCIceTransportPolicy.all,
                //X_BindAddress = IPAddress.Any, // NOTE: Not reqd. Using this to filter out IPv6 addresses so can test with Pion.
            };

            _peerConnection = new RTCPeerConnection(pcConfiguration);

            //_peerConnection.GetRtpChannel().MdnsResolve = (hostname) => Task.FromResult(NetServices.InternetDefaultAddress);
            _peerConnection.GetRtpChannel().MdnsResolve = MdnsResolve;
            //_peerConnection.GetRtpChannel().OnStunMessageReceived += (msg, ep, isrelay) => logger.LogDebug($"STUN message received from {ep}, message type {msg.Header.MessageType}.");

            //var dc = _peerConnection.createDataChannel(DATA_CHANNEL_LABEL, null);
            //dc.onmessage += (msg) => logger.LogDebug($"data channel receive ({dc.label}-{dc.id}): {msg}");

            // Add a send-only audio track (this doesn't require any native libraries for encoding so is good for x-platform testing).
            AudioExtrasSource audioSource = new AudioExtrasSource(new AudioEncoder(), new AudioSourceOptions {
                AudioSource = AudioSourcesEnum.Music
            });

            audioSource.OnAudioSourceEncodedSample += _peerConnection.SendAudio;

            MediaStreamTrack audioTrack = new MediaStreamTrack(audioSource.GetAudioSourceFormats(), MediaStreamStatusEnum.SendOnly);

            _peerConnection.addTrack(audioTrack);

            _peerConnection.OnAudioFormatsNegotiated += (formats) =>
                                                        audioSource.SetAudioSourceFormat(formats.First());

            _peerConnection.onicecandidateerror     += (candidate, error) => logger.LogWarning($"Error adding remote ICE candidate. {error} {candidate}");
            _peerConnection.onconnectionstatechange += async(state) =>
            {
                logger.LogDebug($"Peer connection state changed to {state}.");

                if (state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed)
                {
                    _peerConnection.Close("remote disconnection");
                }

                if (state == RTCPeerConnectionState.connected)
                {
                    await audioSource.StartAudio();
                }
                else if (state == RTCPeerConnectionState.closed)
                {
                    await audioSource.CloseAudio();
                }
            };
            _peerConnection.OnReceiveReport += (re, media, rr) => logger.LogDebug($"RTCP Receive for {media} from {re}\n{rr.GetDebugSummary()}");
            _peerConnection.OnSendReport    += (media, sr) => logger.LogDebug($"RTCP Send for {media}\n{sr.GetDebugSummary()}");
            _peerConnection.OnRtcpBye       += (reason) => logger.LogDebug($"RTCP BYE receive, reason: {(string.IsNullOrWhiteSpace(reason) ? "<none>" : reason)}.");

            // Peer ICE connection state changes are for ICE events such as the STUN checks completing.
            _peerConnection.oniceconnectionstatechange += (state) => logger.LogDebug($"ICE connection state change to {state}.");

            _peerConnection.ondatachannel += (dc) =>
            {
                logger.LogDebug($"Data channel opened by remote peer, label {dc.label}, stream ID {dc.id}.");
                dc.onmessage += (msg) =>
                {
                    logger.LogDebug($"data channel ({dc.label}:{dc.id}): {msg}.");
                };
            };

            _peerConnection.onsignalingstatechange += () =>
            {
                if (_peerConnection.signalingState == RTCSignalingState.have_remote_offer)
                {
                    logger.LogDebug("Remote SDP:");
                    logger.LogDebug(_peerConnection.remoteDescription.sdp.ToString());
                }
                else if (_peerConnection.signalingState == RTCSignalingState.have_local_offer)
                {
                    logger.LogDebug("Local SDP:");
                    logger.LogDebug(_peerConnection.localDescription.sdp.ToString());
                }
            };

            return(Task.FromResult(_peerConnection));
        }
Exemplo n.º 12
0
        private static async Task RunCommand(Options options, bool noOptions)
        {
            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.

            //ManualResetEvent exitMre = new ManualResetEvent(false);

            logger = AddConsoleLogger();

            // Start MDNS server.
            var mdnsServer = new ServiceDiscovery();

            if (options.StunServer != null)
            {
                string[] fields = options.StunServer.Split(';');

                _stunServer = new RTCIceServer
                {
                    urls           = fields[0],
                    username       = fields.Length > 1 ? fields[1] : null,
                    credential     = fields.Length > 2 ? fields[2] : null,
                    credentialType = RTCIceCredentialType.password
                };
            }

            _relayOnly = options.RelayOnly;

            if (!string.IsNullOrEmpty(options.IceTypes))
            {
                options.IceTypes.Split().ToList().ForEach(x =>
                {
                    if (Enum.TryParse <RTCIceCandidateType>(x, out var iceType))
                    {
                        _iceTypes.Add(iceType);
                    }
                });

                if (!_iceTypes.Any(x => x == RTCIceCandidateType.host))
                {
                    _offerOptions = new RTCOfferOptions {
                        X_ExcludeIceCandidates = true
                    };
                    _answerOptions = new RTCAnswerOptions {
                        X_ExcludeIceCandidates = true
                    };
                }
            }

            if (!string.IsNullOrEmpty(options.AcceptIceTypes))
            {
                options.AcceptIceTypes.Split().ToList().ForEach(x =>
                {
                    if (Enum.TryParse <RTCIceCandidateType>(x, out var iceType))
                    {
                        _acceptIceTypes.Add(iceType);
                    }
                });
            }

            if (options.UseWebSocket || options.UseSecureWebSocket || noOptions)
            {
                // Start web socket.
                Console.WriteLine("Starting web socket server...");
                _webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT, options.UseSecureWebSocket);
                if (options.UseSecureWebSocket)
                {
                    _webSocketServer.SslConfiguration.ServerCertificate          = new X509Certificate2(LOCALHOST_CERTIFICATE_PATH);
                    _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;
                }
                _webSocketServer.AddWebSocketService <WebRTCWebSocketPeer>("/", (peer) =>
                {
                    peer.OfferOptions = _offerOptions;
                    if (_acceptIceTypes != null && _acceptIceTypes.Count > 0)
                    {
                        peer.FilterRemoteICECandidates = (init) => _acceptIceTypes.Any(x => x == RTCIceCandidate.Parse(init.candidate).type);
                    }
                    peer.CreatePeerConnection = CreatePeerConnection;
                });
                _webSocketServer.Start();

                Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");
            }
            else if (!string.IsNullOrWhiteSpace(options.WebSocketServer))
            {
                // We are the client for a web socket server. The JSON signalling exchange still occurs the same way as when the web socket
                // server option is used except that as the web socket client we receive the SDP offer from the server.
                WebRTCWebSocketClient wsockClient = new WebRTCWebSocketClient(options.WebSocketServer, CreatePeerConnection);
                await wsockClient.Start(exitCts.Token);

                Console.WriteLine("web socket client started.");
            }
            else if (options.CreateJsonOffer)
            {
                var pc = await Createpc(null, _stunServer, _relayOnly);

                var offerSdp = pc.createOffer(null);
                await pc.setLocalDescription(offerSdp);

                Console.WriteLine(offerSdp.sdp);

                var offerJson   = JsonConvert.SerializeObject(offerSdp, new Newtonsoft.Json.Converters.StringEnumConverter());
                var offerBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(offerJson));

                Console.WriteLine(offerBase64);

                string remoteAnswerB64 = null;
                while (string.IsNullOrWhiteSpace(remoteAnswerB64))
                {
                    Console.Write("Remote Answer => ");
                    remoteAnswerB64 = Console.ReadLine();
                }

                string remoteAnswer = Encoding.UTF8.GetString(Convert.FromBase64String(remoteAnswerB64));

                Console.WriteLine(remoteAnswer);

                RTCSessionDescriptionInit answerInit = JsonConvert.DeserializeObject <RTCSessionDescriptionInit>(remoteAnswer);

                Console.WriteLine($"Remote answer: {answerInit.sdp}");

                var res = pc.setRemoteDescription(answerInit);
                if (res != SetDescriptionResultEnum.OK)
                {
                    // No point continuing. Something will need to change and then try again.
                    pc.Close("failed to set remote sdp");
                }
            }
            else if (options.RestServer != null)
            {
                string[] fields = options.RestServer.Split(';');
                if (fields.Length < 3)
                {
                    throw new ArgumentException("The 'rest' option must contain 3 semi-colon separated fields, e.g. --rest=https://localhost:5001/api/webrtcsignal;myid;theirid.");
                }

                var webrtcRestPeer = new WebRTCRestSignalingPeer(fields[0], fields[1], fields[2], CreatePeerConnection);
                webrtcRestPeer.OfferOptions  = _offerOptions;
                webrtcRestPeer.AnswerOptions = _answerOptions;

                if (_acceptIceTypes != null && _acceptIceTypes.Count > 0)
                {
                    webrtcRestPeer.FilterRemoteICECandidates = (init) => _acceptIceTypes.Any(x => x == RTCIceCandidate.Parse(init.candidate).type);
                }
                await webrtcRestPeer.Start(exitCts);
            }

            _ = Task.Run(() => ProcessInput(exitCts));

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitCts.Cancel();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitCts.Token.WaitHandle.WaitOne();

            Console.WriteLine();
            Console.WriteLine("Exiting...");

            _peerConnection?.Close("application exit");

            _webSocketServer?.Stop();

            Task.Delay(1000).Wait();
        }
Exemplo n.º 13
0
        private static RTCPeerConnection Createpc(WebSocketContext context, RTCIceServer stunServer)
        {
            if (_peerConnection != null)
            {
                _peerConnection.Close("normal");
            }

            List <RTCCertificate> presetCertificates = null;

            if (File.Exists(LOCALHOST_CERTIFICATE_PATH))
            {
                var localhostCert = new X509Certificate2(LOCALHOST_CERTIFICATE_PATH, (string)null, X509KeyStorageFlags.Exportable);
                presetCertificates = new List <RTCCertificate> {
                    new RTCCertificate {
                        Certificate = localhostCert
                    }
                };
            }

            RTCConfiguration pcConfiguration = new RTCConfiguration
            {
                certificates = presetCertificates,
                X_RemoteSignallingAddress = (context != null) ? context.UserEndPoint.Address : null,
                iceServers = stunServer != null ? new List <RTCIceServer> {
                    stunServer
                } : null,
                iceTransportPolicy = RTCIceTransportPolicy.all,
                //X_BindAddress = IPAddress.Any, // NOTE: Not reqd. Using this to filter out IPv6 addresses so can test with Pion.
            };

            _peerConnection = new RTCPeerConnection(pcConfiguration);

            //_peerConnection.GetRtpChannel().MdnsResolve = (hostname) => Task.FromResult(NetServices.InternetDefaultAddress);
            _peerConnection.GetRtpChannel().MdnsResolve            = MdnsResolve;
            _peerConnection.GetRtpChannel().OnStunMessageReceived += (msg, ep, isrelay) => logger.LogDebug($"STUN message received from {ep}, message class {msg.Header.MessageClass}.");

            var dc = _peerConnection.createDataChannel(DATA_CHANNEL_LABEL, null);

            dc.onmessage += (msg) => logger.LogDebug($"data channel receive ({dc.label}-{dc.id}): {msg}");

            // Add inactive audio and video tracks.
            //MediaStreamTrack audioTrack = new MediaStreamTrack(SDPMediaTypesEnum.audio, false, new List<SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.PCMU) }, MediaStreamStatusEnum.RecvOnly);
            //pc.addTrack(audioTrack);
            //MediaStreamTrack videoTrack = new MediaStreamTrack(SDPMediaTypesEnum.video, false, new List<SDPMediaFormat> { new SDPMediaFormat(SDPMediaFormatsEnum.VP8) }, MediaStreamStatusEnum.Inactive);
            //pc.addTrack(videoTrack);

            _peerConnection.onicecandidateerror     += (candidate, error) => logger.LogWarning($"Error adding remote ICE candidate. {error} {candidate}");
            _peerConnection.onconnectionstatechange += (state) =>
            {
                logger.LogDebug($"Peer connection state changed to {state}.");

                if (state == RTCPeerConnectionState.disconnected || state == RTCPeerConnectionState.failed)
                {
                    _peerConnection.Close("remote disconnection");
                }
            };
            _peerConnection.OnReceiveReport += (ep, type, rtcp) => logger.LogDebug($"RTCP {type} report received.");
            _peerConnection.OnRtcpBye       += (reason) => logger.LogDebug($"RTCP BYE receive, reason: {(string.IsNullOrWhiteSpace(reason) ? "<none>" : reason)}.");

            _peerConnection.onicecandidate += (candidate) =>
            {
                if (_peerConnection.signalingState == RTCSignalingState.have_local_offer ||
                    _peerConnection.signalingState == RTCSignalingState.have_remote_offer)
                {
                    if (context != null)
                    {
                        context.WebSocket.Send($"candidate:{candidate}");
                    }
                }
            };

            // Peer ICE connection state changes are for ICE events such as the STUN checks completing.
            _peerConnection.oniceconnectionstatechange += (state) =>
            {
                logger.LogDebug($"ICE connection state change to {state}.");
            };

            _peerConnection.ondatachannel += (dc) =>
            {
                logger.LogDebug($"Data channel opened by remote peer, label {dc.label}, stream ID {dc.id}.");
                dc.onmessage += (msg) =>
                {
                    logger.LogDebug($"data channel ({dc.label}:{dc.id}): {msg}.");
                };
            };

            return(_peerConnection);
        }
Exemplo n.º 14
0
        private static async Task RunCommand(Options options, bool noOptions)
        {
            // Plumbing code to facilitate a graceful exit.
            CancellationTokenSource exitCts = new CancellationTokenSource(); // Cancellation token to stop the SIP transport and RTP stream.

            //ManualResetEvent exitMre = new ManualResetEvent(false);

            AddConsoleLogger();

            // Start MDNS server.
            var mdnsServer = new ServiceDiscovery();

            if (options.StunServer != null)
            {
                string[] fields = options.StunServer.Split(';');

                _stunServer = new RTCIceServer
                {
                    urls           = fields[0],
                    username       = fields.Length > 1 ? fields[1] : null,
                    credential     = fields.Length > 2 ? fields[2] : null,
                    credentialType = RTCIceCredentialType.password
                };
            }

            if (options.UseWebSocket || options.UseSecureWebSocket || noOptions)
            {
                // Start web socket.
                Console.WriteLine("Starting web socket server...");
                _webSocketServer = new WebSocketServer(IPAddress.Any, WEBSOCKET_PORT, options.UseSecureWebSocket);

                if (options.UseSecureWebSocket)
                {
                    _webSocketServer.SslConfiguration.ServerCertificate          = new System.Security.Cryptography.X509Certificates.X509Certificate2(LOCALHOST_CERTIFICATE_PATH);
                    _webSocketServer.SslConfiguration.CheckCertificateRevocation = false;
                }

                //_webSocketServer.Log.Level = WebSocketSharp.LogLevel.Debug;
                _webSocketServer.AddWebSocketService <WebRtcClient>("/sendoffer", (client) =>
                {
                    client.WebSocketOpened   += SendOffer;
                    client.OnMessageReceived += WebSocketMessageReceived;
                });
                _webSocketServer.AddWebSocketService <WebRtcClient>("/receiveoffer", (client) =>
                {
                    client.WebSocketOpened   += ReceiveOffer;
                    client.OnMessageReceived += WebSocketMessageReceived;
                });
                _webSocketServer.Start();

                Console.WriteLine($"Waiting for browser web socket connection to {_webSocketServer.Address}:{_webSocketServer.Port}...");
            }
            else if (options.CreateJsonOffer)
            {
                var pc = Createpc(null, _stunServer);

                var offerSdp = pc.createOffer(null);
                await pc.setLocalDescription(offerSdp);

                Console.WriteLine(offerSdp.sdp);

                var offerJson   = JsonConvert.SerializeObject(offerSdp, new Newtonsoft.Json.Converters.StringEnumConverter());
                var offerBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(offerJson));

                Console.WriteLine(offerBase64);

                string remoteAnswerB64 = null;
                while (string.IsNullOrWhiteSpace(remoteAnswerB64))
                {
                    Console.Write("Remote Answer => ");
                    remoteAnswerB64 = Console.ReadLine();
                }

                string remoteAnswer = Encoding.UTF8.GetString(Convert.FromBase64String(remoteAnswerB64));

                Console.WriteLine(remoteAnswer);

                RTCSessionDescriptionInit answerInit = JsonConvert.DeserializeObject <RTCSessionDescriptionInit>(remoteAnswer);

                Console.WriteLine($"Remote answer: {answerInit.sdp}");

                var res = pc.setRemoteDescription(answerInit);
                if (res != SetDescriptionResultEnum.OK)
                {
                    // No point continuing. Something will need to change and then try again.
                    pc.Close("failed to set remote sdp");
                }
            }
            else if (options.NodeDssServer != null)
            {
                _nodeDssUri    = new Uri(options.NodeDssServer);
                _nodeDssclient = new HttpClient();

                Console.WriteLine($"node-dss server successfully set to {_nodeDssUri}.");
            }

            _ = Task.Run(() => ProcessInput(exitCts));

            // Ctrl-c will gracefully exit the call at any point.
            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                exitCts.Cancel();
            };

            // Wait for a signal saying the call failed, was cancelled with ctrl-c or completed.
            exitCts.Token.WaitHandle.WaitOne();

            Console.WriteLine();
            Console.WriteLine("Exiting...");

            _peerConnection?.Close("application exit");

            _webSocketServer?.Stop();

            Task.Delay(1000).Wait();
        }
Exemplo n.º 15
0
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            RTCIceGatherOptions options = new RTCIceGatherOptions();
            RTCIceServer        server  = new RTCIceServer();

            server.UserName   = "******";
            server.Credential = "12345";
            server.Urls       = new List <String>();
            server.Urls.Add("stun:stun.vline.com");
            options.IceServers = new List <RTCIceServer>();
            options.IceServers.Add(server);

            _iceGatherer = new RTCIceGatherer(options);
            _iceGatherer.OnStateChange            += this.RTCIceGatherer_onICEGathererStateChanged;
            _iceGatherer.OnLocalCandidate         += this.RTCIceGatherer_onICEGathererLocalCandidate;
            _iceGatherer.OnLocalCandidateComplete += this.RTCIceGatherer_onICEGathererCandidateComplete;
            _iceGatherer.OnLocalCandidateGone     += this.RTCIceGatherer_onICEGathererLocalCandidateGone;
            _iceGatherer.OnError += this.RTCIceGatherer_onICEGathererError;


            _iceGatherer2 = new RTCIceGatherer(options);
            _iceGatherer2.OnStateChange            += this.RTCIceGatherer_onICEGathererStateChanged2;
            _iceGatherer2.OnLocalCandidate         += this.RTCIceGatherer_onICEGathererLocalCandidate2;
            _iceGatherer2.OnLocalCandidateComplete += this.RTCIceGatherer_onICEGathererCandidateComplete2;
            _iceGatherer2.OnLocalCandidateGone     += this.RTCIceGatherer_onICEGathererLocalCandidateGone2;
            _iceGatherer2.OnError += this.RTCIceGatherer_onICEGathererError;

            _iceTransport = new RTCIceTransport(_iceGatherer);
            _iceTransport.OnStateChange            += RTCIceTransport_onICETransportStateChanged;
            _iceTransport.OnCandidatePairAvailable += RTCIceTransport_onICETransportCandidatePairAvailable;
            _iceTransport.OnCandidatePairGone      += RTCIceTransport_onICETransportCandidatePairGone;
            _iceTransport.OnCandidatePairChange    += RTCIceTransport_onICETransportCandidatePairChanged;

            _iceTransport2 = new RTCIceTransport(_iceGatherer);
            _iceTransport2.OnStateChange            += RTCIceTransport_onICETransportStateChanged2;
            _iceTransport2.OnCandidatePairAvailable += RTCIceTransport_onICETransportCandidatePairAvailable2;
            _iceTransport2.OnCandidatePairGone      += RTCIceTransport_onICETransportCandidatePairGone2;
            _iceTransport2.OnCandidatePairChange    += RTCIceTransport_onICETransportCandidatePairChanged2;

            RTCCertificate.GenerateCertificate().AsTask <RTCCertificate>().ContinueWith((cert) =>
            {
                String str = cert.Result.Expires.ToString();
                List <RTCCertificate> certs = new List <RTCCertificate>();
                certs.Add(cert.Result);
                _dtlsTransport = new RTCDtlsTransport(_iceTransport, certs);
                MediaStreamConstraints constraints = new MediaStreamConstraints();

                constraints.Audio = new MediaTrackConstraints();
                constraints.Video = new MediaTrackConstraints();

                MediaDevices.GetUserMedia(constraints).AsTask().ContinueWith <IList <MediaStreamTrack> >((temp) =>
                {
                    if (temp.Result != null && temp.Result.Count() > 0)
                    {
                        List <MediaStreamTrack> ret = new List <MediaStreamTrack>(temp.Result);
                        List <RTCRtpSender> senders = new List <RTCRtpSender>();
                        foreach (MediaStreamTrack track in temp.Result)
                        {
                            RTCRtpSender rtpSender = new RTCRtpSender(track, _dtlsTransport);
                            senders.Add(rtpSender);
                        }

                        return(ret);
                    }

                    return(null);
                });
            });

            RTCCertificate.GenerateCertificate().AsTask <RTCCertificate>().ContinueWith((cert) =>
            {
                var certs = new List <RTCCertificate>();
                certs.Add(cert.Result);
                _dtlsTransport2 = new RTCDtlsTransport(_iceTransport2, certs);
            });

            MediaDevices.EnumerateDevices().AsTask().ContinueWith <MediaDeviceInfo>((temp) =>
            {
                foreach (MediaDeviceInfo info in temp.Result)
                {
                    if (info.DeviceId != null)
                    {
                        System.Diagnostics.Debug.WriteLine("DeviceID: {0}", info.DeviceId);
                    }
                }
                return(null);
            });
        }
Exemplo n.º 16
0
 public static Core.IceServer ToNativePort(this RTCIceServer platformNative) => new Core.IceServer(urlStrings: platformNative.UrlStrings, username: platformNative.Username, credential: platformNative.Credential, policy: platformNative.TlsCertPolicy.ToNativePort(), hostname: platformNative.Hostname, tlsEllipticCurves: platformNative.TlsEllipticCurves, tlsAlpnProtocols: platformNative.TlsAlpnProtocols);