コード例 #1
0
        public async Task Initialization(string user)
        {
            try
            {
                var config = new PeerConnectionConfiguration
                {
                    IceServers = new List <IceServer> {
                        new IceServer {
                            Urls = { "stun:stun.l.google.com:19302" }
                        }
                    }
                };
                await Connection.InitializeAsync(config);

                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;

                Console.WriteLine("Peer connection initialized.");
            }
            catch (Exception e)
            {
                await Log.WriteAsync(e.Message);

                Console.WriteLine(e);
                throw;
            }
        }
コード例 #2
0
        /// <summary>
        /// Initialize the underlying WebRTC peer connection.
        /// </summary>
        /// <remarks>
        /// This method is asynchronous and completes its task when the initializing completed.
        /// On successful completion, it also trigger the <see cref="OnInitialized"/> event.
        /// Note however that this completion is free-threaded and complete immediately when the
        /// underlying peer connection is initialized, whereas any <see cref="OnInitialized"/>
        /// event handler is invoked when control returns to the main Unity app thread. The former
        /// is faster, but does not allow accessing the underlying peer connection because it
        /// returns before <see cref="OnPostInitialize"/> executed. Therefore it is generally
        /// recommended to listen to the <see cref="OnInitialized"/> event, and ignore the returned
        /// <see xref="System.Threading.Tasks.Task"/> object.
        /// </remarks>
        private async Task <WebRTC.PeerConnection> InitializePluginAsync(CancellationToken token)
        {
            // Ensure Android binding is initialized before accessing the native implementation
            Android.Initialize();

#if UNITY_WSA && !UNITY_EDITOR
            if (Library.UsedAudioDeviceModule == AudioDeviceModule.LegacyModule)
            {
                // Preventing access to audio crashes the ADM1 at startup and the entire application.
                bool permissionGranted = await UwpUtils.RequestAccessAsync(StreamingCaptureMode.Audio);

                if (!permissionGranted)
                {
                    return(null);
                }
            }
#endif
            // Create the peer connection managed wrapper and its native implementation
            var nativePeer = new WebRTC.PeerConnection();

            nativePeer.AudioTrackAdded +=
                (RemoteAudioTrack track) =>
            {
                // Tracks will be output by AudioReceivers, so avoid outputting them twice.
                track.OutputToDevice(false);
            };

            Debug.Log("Initializing WebRTC Peer Connection...");
            var config = new PeerConnectionConfiguration();
            foreach (var server in IceServers)
            {
                config.IceServers.Add(new IceServer
                {
                    Urls         = { server.ToString() },
                    TurnUserName = IceUsername,
                    TurnPassword = IceCredential
                });
            }

            try
            {
                await nativePeer.InitializeAsync(config, token);

                return(nativePeer);
            }
            catch (OperationCanceledException canceled) { throw canceled; }
            catch (Exception ex)
            {
                nativePeer.Dispose();
                token.ThrowIfCancellationRequested();

                EnsureIsMainAppThread();
                var errorMessage = new StringBuilder();
                errorMessage.Append("WebRTC plugin initializing failed. See full log for exception details.\n");
                errorMessage.Append($"Exception: {ex.Message}");
                OnError.Invoke(errorMessage.ToString());
                throw ex;
            }
        }
コード例 #3
0
 public async void PeerConnectionDefault()
 {
     using (var pc = new PeerConnection())
     {
         var config = new PeerConnectionConfiguration();
         await pc.InitializeAsync(config);
     }
 }
コード例 #4
0
        public async Task SctpError()
        {
            // Setup
            var config = new PeerConnectionConfiguration();
            var pc1    = new PeerConnection();
            var pc2    = new PeerConnection();
            await pc1.InitializeAsync(config);

            await pc2.InitializeAsync(config);

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

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

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

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

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

            // Clean-up
            pc1.Close();
            pc1.Dispose();
            pc2.Close();
            pc2.Dispose();
        }
コード例 #5
0
        /// <summary>
        /// Initialize the peer connection.
        /// </summary>
        /// <returns>A task that completes once the peer connection is ready to be used.</returns>
        public async Task InitializePeerConnectionAsync()
        {
            Logger.Log("Initializing the peer connection...");

            // Cannot run in UI thread on UWP because this will initialize the global factory
            // (first library call) which needs to be done on a background thread.
            await ThreadHelper.RunOnWorkerThread(() => Library.ShutdownOptions = Library.ShutdownOptionsFlags.LogLiveObjects);

            // Initialize the native peer connection object
            try
            {
                var config = new PeerConnectionConfiguration
                {
                    SdpSemantic = _sdpSemantic,
                    IceServers  = new List <IceServer> {
                        _iceServer
                    }
                };
                await _peerConnection.InitializeAsync(config);

                RaisePropertyChanged("IsPeerInitialized");
            }
            catch (Exception ex)
            {
                Logger.Log($"WebRTC native plugin init failed: {ex.Message}");
                throw ex;
            }
            Logger.Log("Peer connection initialized.");
            OnPeerInitialized();

            //using (_sessionViewModel.GetNegotiationDeferral())
            {
                //// As a convenience, add 1 audio and 1 video transceivers
                //// TODO - make that more flexible
                //AddPendingTransceiver(MediaKind.Audio, "audio_transceiver_0");
                //AddPendingTransceiver(MediaKind.Video, "video_transceiver_1");

                // It is CRUCIAL to add any data channel BEFORE the SDP offer is sent, if data channels are
                // to be used at all. Otherwise the SCTP will not be negotiated, and then all channels will
                // stay forever in the kConnecting state.
                // https://stackoverflow.com/questions/43788872/how-are-data-channels-negotiated-between-two-peers-with-webrtc
                await _peerConnection.AddDataChannelAsync(ChatChannelID, "chat", true, true);
            }

            //_videoPlayer.CurrentStateChanged += OnMediaStateChanged;
            //_videoPlayer.MediaOpened += OnMediaOpened;
            //_videoPlayer.MediaFailed += OnMediaFailed;
            //_videoPlayer.MediaEnded += OnMediaEnded;
            //_videoPlayer.RealTimePlayback = true;
            //_videoPlayer.AutoPlay = false;

            // Bind the XAML UI control (videoPlayerElement) to the MediaFoundation rendering pipeline (_videoPlayer)
            // so that the former can render in the UI the video frames produced in the background by the latter.
            //videoPlayerElement.SetMediaPlayer(_videoPlayer);
        }
コード例 #6
0
        protected async Task MakeICECall(PeerConnection pc1, PeerConnection pc2)
        {
            var evExchangeCompleted = new ManualResetEventSlim(initialState: false);

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

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

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

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

            await pc2.InitializeAsync(pcConfig);

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

            pc1.Connected += () => ev1.Set();
            pc2.Connected += () => ev2.Set();
            evExchangeCompleted.Reset();
            pc1.CreateOffer();
            ev1.Wait(millisecondsTimeout: 5000);
            ev2.Wait(millisecondsTimeout: 5000);
            evExchangeCompleted.Wait(millisecondsTimeout: 5000);
        }
コード例 #7
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);
            }
        }
コード例 #8
0
        private static PeerConnectionConfiguration CreateSetting()
        {
            // Here the main settings of PeerConnection object
            // If you want to someone change in settings of PeerConnection objects
            // You can make it here
            PeerConnectionConfiguration setting = new PeerConnectionConfiguration();

            setting.IceServers.AddRange(LoadFromConfigAllSTUN());
            setting.IceServers.AddRange(LoadFromConfigAllTURN());
            //Console.WriteLine("Creating PeerConnection");
            return(setting);
        }
コード例 #9
0
ファイル: Startup.cs プロジェクト: Ogurecher/Team-Link
        private async Task InitializeWebRTC(HttpContext context, WebSocket webSocket)
        {
            Console.WriteLine("Initializing WebRTC");

            var config = new PeerConnectionConfiguration
            {
                IceServers = new List <IceServer> {
                    new IceServer {
                        Urls = { Config.STUN_URI }
                    }
                }
            };

            await this.peerConnection.InitializeAsync(config);

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

            var signaler = new WebSocketSignaler(this.peerConnection, webSocket);

            signaler.SdpMessageReceived += async(SdpMessage message) => {
                await this.peerConnection.SetRemoteDescriptionAsync(message);

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

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

            this.peerConnection.Connected += () => {
                Console.WriteLine("!!! --- PeerConnection: connected --- !!!");
            };

            this.peerConnection.IceStateChanged += (IceConnectionState newState) => {
                Console.WriteLine($"!!! --- ICE state: {newState} --- !!!");
            };

            this.peerConnection.RenegotiationNeeded += () => {
                this.peerConnection.CreateOffer();
            };

            await signaler.StartAsync();

            Console.WriteLine("Signaler started");
            Console.Read();
            signaler.Stop();
            this.peerConnection.Close();
            Console.WriteLine("Program terminated.");
        }
コード例 #10
0
        public async Task LocalNoICE()
        {
            var pc1 = new PeerConnection();
            var pc2 = new PeerConnection();

            var evExchangeCompleted = new ManualResetEventSlim(initialState: false);

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

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

                if (message.Type == SdpMessageType.Offer)
                {
                    pc1.CreateAnswer();
                }
                else
                {
                    evExchangeCompleted.Set();
                }
            };

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

            await pc2.InitializeAsync(pcConfig);

            var ev1 = new ManualResetEventSlim(initialState: false);

            pc1.Connected += () => ev1.Set();
            evExchangeCompleted.Reset();
            pc1.CreateOffer();
            ev1.Wait(millisecondsTimeout: 5000);
            evExchangeCompleted.Wait(millisecondsTimeout: 5000);

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

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

            await pc2.InitializeAsync(pcConfig);

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

            pc1.Connected += () => ev1.Set();
            pc2.Connected += () => ev2.Set();
            pc1.CreateOffer();
            ev1.Wait(millisecondsTimeout: 5000);
            ev2.Wait(millisecondsTimeout: 5000);
        }
        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);
        }
コード例 #13
0
        /// <summary>
        /// Internal handler to actually initialize the
        /// </summary>
        private Task InitializePluginAsync(CancellationToken token)
        {
            Debug.Log("Initializing WebRTC plugin...");
            var config = new PeerConnectionConfiguration();

            foreach (var server in IceServers)
            {
                config.IceServers.Add(new IceServer
                {
                    Urls         = { server.ToString() },
                    TurnUserName = IceUsername,
                    TurnPassword = IceCredential
                });
            }
            return(_nativePeer.InitializeAsync(config, token).ContinueWith((initTask) =>
            {
                token.ThrowIfCancellationRequested();

                if (initTask.Exception != null)
                {
                    _mainThreadWorkQueue.Enqueue(() =>
                    {
                        var errorMessage = new StringBuilder();
                        errorMessage.Append("WebRTC plugin initializing failed. See full log for exception details.\n");
                        Exception ex = initTask.Exception;
                        while (ex is AggregateException ae)
                        {
                            errorMessage.Append($"AggregationException: {ae.Message}\n");
                            ex = ae.InnerException;
                        }
                        errorMessage.Append($"Exception: {ex.Message} {ex.ToString()}");
                        OnError.Invoke(errorMessage.ToString());
                    });
                    throw initTask.Exception;
                }

                _mainThreadWorkQueue.Enqueue(OnPostInitialize);
            }, token));
        }
コード例 #14
0
        public async Task LocalNoICE()
        {
            var pc1 = new PeerConnection();
            var pc2 = new PeerConnection();

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

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

                if (type == "offer")
                {
                    pc1.CreateAnswer();
                }
            };

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

            await pc2.InitializeAsync(pcConfig);

            var ev1 = new ManualResetEventSlim(initialState: false);

            pc1.Connected += () => ev1.Set();
            pc1.CreateOffer();
            ev1.Wait(millisecondsTimeout: 5000);

            pc1.Close();
            pc2.Close();
        }
コード例 #15
0
        public void SetupConnection()
        {
            // Create the 2 peers
            var config = new PeerConnectionConfiguration();

            pc1_ = new PeerConnection();
            pc2_ = new PeerConnection();
            pc1_.InitializeAsync(config).Wait(); // cannot use async/await in OneTimeSetUp
            pc2_.InitializeAsync(config).Wait();

            // Allocate callback events
            connectedEvent1_     = new ManualResetEventSlim(false);
            connectedEvent2_     = new ManualResetEventSlim(false);
            iceConnectedEvent1_  = new ManualResetEventSlim(false);
            iceConnectedEvent2_  = new ManualResetEventSlim(false);
            renegotiationEvent1_ = new ManualResetEventSlim(false);
            renegotiationEvent2_ = new ManualResetEventSlim(false);
            trackAddedEvent1_    = new ManualResetEventSlim(false);
            trackAddedEvent2_    = new ManualResetEventSlim(false);
            trackRemovedEvent1_  = new ManualResetEventSlim(false);
            trackRemovedEvent2_  = new ManualResetEventSlim(false);

            // Connect all signals
            pc1_.Connected               += OnConnected1;
            pc2_.Connected               += OnConnected2;
            pc1_.LocalSdpReadytoSend     += OnLocalSdpReady1;
            pc2_.LocalSdpReadytoSend     += OnLocalSdpReady2;
            pc1_.IceCandidateReadytoSend += OnIceCandidateReadytoSend1;
            pc2_.IceCandidateReadytoSend += OnIceCandidateReadytoSend2;
            pc1_.IceStateChanged         += OnIceStateChanged1;
            pc2_.IceStateChanged         += OnIceStateChanged2;
            pc1_.RenegotiationNeeded     += OnRenegotiationNeeded1;
            pc2_.RenegotiationNeeded     += OnRenegotiationNeeded2;
            pc1_.TrackAdded              += OnTrackAdded1;
            pc2_.TrackAdded              += OnTrackAdded2;
            pc1_.TrackRemoved            += OnTrackRemoved1;
            pc2_.TrackRemoved            += OnTrackRemoved2;
        }
コード例 #16
0
        public async Task Init(IceServerModel[] iceServers)
        {
            Logger.Debug("Starting WebRTC connection.");

            IceServers = iceServers;

            PeerSession = new PeerConnection();

            var iceList = IceServers.Select(x => new IceServer()
            {
                Urls         = { x.Url },
                TurnPassword = x.TurnPassword ?? string.Empty,
                TurnUserName = x.TurnUsername ?? string.Empty
            }).ToList();

            var config = new PeerConnectionConfiguration()
            {
                IceServers = iceList
            };

            await PeerSession.InitializeAsync(config);

            PeerSession.LocalSdpReadytoSend     += PeerSession_LocalSdpReadytoSend;;
            PeerSession.Connected               += PeerConnection_Connected;
            PeerSession.IceStateChanged         += PeerConnection_IceStateChanged;
            PeerSession.IceCandidateReadytoSend += PeerSession_IceCandidateReadytoSend;;

            CaptureChannel = await PeerSession.AddDataChannelAsync("ScreenCapture", true, true);

            CaptureChannel.BufferingChanged += DataChannel_BufferingChanged;
            CaptureChannel.MessageReceived  += CaptureChannel_MessageReceived;
            CaptureChannel.StateChanged     += CaptureChannel_StateChanged;

            VideoSource = ExternalVideoTrackSource.CreateFromArgb32Callback(GetCaptureFrame);
            Transceiver = PeerSession.AddTransceiver(MediaKind.Video);

            PeerSession.CreateOffer();
        }
コード例 #17
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 ");
            }
        }
コード例 #18
0
        static async Task Main()
        {
            try
            {
                Console.WriteLine("Starting...");
                //create and Initialize capture object to record audio
                var           waveFormat = new WaveFormat(44100, 32, 2, AudioEncoding.MpegLayer3);
                WasapiCapture capture    = new WasapiCapture(true, AudioClientShareMode.Shared, 100, waveFormat);

                //initialize the selected device for recording
                capture.Initialize();
                //fill ice servers here
                List <string> urls = new List <string>();


                using var pc = new PeerConnection();

                var config = new PeerConnectionConfiguration
                {
                    IceServers = new List <IceServer> {
                        new IceServer {
                            Urls = urls,
                        }
                    }
                    ,
                    BundlePolicy = BundlePolicy.MaxBundle
                };

                await pc.InitializeAsync(config);

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


                //create audio transceiver
                Transceiver transceiver = pc.AddTransceiver(MediaKind.Audio);
                transceiver.DesiredDirection = Transceiver.Direction.ReceiveOnly;
                Console.WriteLine("Create audio transceiver ...");

                DataChannel chanel = await pc.AddDataChannelAsync("Data", true, true, cancellationToken : default);

                string url = "";
                WebSocketSharp.WebSocket signaling = new WebSocket(url);
                signaling.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12;

                signaling.OnMessage += async(sender, message) =>
                {
                    try
                    {
                        //response messages may differ from service provider to another, adjust WebsocketResponse object accordingly
                        var messageObject = JsonConvert.DeserializeObject <WebsocketResponse>(message.Data);
                        var mess          = new SdpMessage {
                            Content = messageObject.Data.Sdp, Type = SdpMessage.StringToType("answer")
                        };

                        if (!string.IsNullOrEmpty(mess.Content))
                        {
                            Console.WriteLine("Sdpmessage: {0}, Type: {1}", mess.Content, mess.Type);
                            await pc.SetRemoteDescriptionAsync(mess);

                            if (mess.Type == SdpMessageType.Answer)
                            {
                                bool res = pc.CreateAnswer();
                                Console.WriteLine("Answer created? {0}", res);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                };


                signaling.OnError += (sender, e) =>
                {
                    Console.WriteLine(e.Message, e.Exception);
                };
                signaling.OnOpen += (sender, e) =>
                {
                    pc.CreateOffer();
                    Console.WriteLine("open");
                };
                signaling.Connect();

                transceiver.Associated += (tranciever) =>
                {
                    Console.WriteLine("Transivier: {0}, {1}", tranciever.Name, tranciever.StreamIDs);
                };



                pc.LocalSdpReadytoSend += (SdpMessage message) =>
                {
                    Console.WriteLine(message.Content);

                    //modify the offer message according to your need

                    var data = new
                    {
                        streamId = "",
                        sdp      = message.Content
                    };
                    var payload = JsonConvert.SerializeObject(new
                    {
                        type    = "cmd",
                        transId = 0,
                        name    = "view",
                        data    = data
                    });
                    Console.WriteLine("Sdp offer to send: " + payload);

                    signaling.Send(payload);
                };


                pc.RenegotiationNeeded += () =>
                {
                    Console.WriteLine("Regotiation needed");
                };

                //when a remote audio track is added, start recording
                pc.AudioTrackAdded += (RemoteAudioTrack track) =>
                {
                    //create a wavewriter to write the data to
                    WaveWriter w = new WaveWriter("audio.mp3", capture.WaveFormat);

                    //setup an eventhandler to receive the recorded data
                    capture.DataAvailable += (s, e) =>
                    {
                        //save the recorded audio
                        w.Write(e.Data, e.Offset, e.ByteCount);
                    };

                    //start recording
                    capture.Start();
                    //this should output the sound
                    track.OutputToDevice(true);

                    //track.AudioFrameReady += (AudioFrame frame) =>
                    //{
                    //you can print anything here if you want to make sure that's you're recieving audio

                    //};
                };


                pc.Connected += () =>
                {
                    Console.WriteLine("Connected");
                    Console.WriteLine(pc.DataChannels.Count);
                };
                pc.IceStateChanged += (IceConnectionState newState) =>
                {
                    Console.WriteLine($"ICE state: {newState}");
                };

                Console.WriteLine("Press enter to stop");
                Console.ReadLine();

                //stop recording
                capture.Stop();
                pc.Close();
                signaling.Close();
                Console.WriteLine("Program termined.");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
コード例 #19
0
        /// <summary>
        /// Initialize the peer connection.
        /// </summary>
        /// <returns>A task that completes once the peer connection is ready to be used.</returns>
        public async Task InitializePeerConnectionAsync()
        {
            Logger.Log("Initializing the peer connection...");

            // Cannot run in UI thread on UWP because this will initialize the global factory
            // (first library call) which needs to be done on a background thread.
            await ThreadHelper.RunOnWorkerThread(() => Library.ShutdownOptions = Library.ShutdownOptionsFlags.LogLiveObjects);

            // Initialize the native peer connection object
            try
            {
                var config = new PeerConnectionConfiguration
                {
                    SdpSemantic = _sdpSemantic,
                    IceServers  = new List <IceServer> {
                        _iceServer
                    }
                };
                await _peerConnection.InitializeAsync(config);

                RaisePropertyChanged("IsPeerInitialized");
            }
            catch (Exception ex)
            {
                Logger.Log($"WebRTC native plugin init failed: {ex.Message}");
                throw ex;
            }
            Logger.Log("Peer connection initialized.");
            OnPeerInitialized();

            // It is CRUCIAL to add any data channel BEFORE the SDP offer is sent, if data channels are
            // to be used at all. Otherwise the SCTP will not be negotiated, and then all channels will
            // stay forever in the kConnecting state.
            // https://stackoverflow.com/questions/43788872/how-are-data-channels-negotiated-between-two-peers-with-webrtc
            await _peerConnection.AddDataChannelAsync(ChatChannelID, "chat", true, true);

            //_videoPlayer.CurrentStateChanged += OnMediaStateChanged;
            //_videoPlayer.MediaOpened += OnMediaOpened;
            //_videoPlayer.MediaFailed += OnMediaFailed;
            //_videoPlayer.MediaEnded += OnMediaEnded;
            //_videoPlayer.RealTimePlayback = true;
            //_videoPlayer.AutoPlay = false;

            // Bind the XAML UI control (videoPlayerElement) to the MediaFoundation rendering pipeline (_videoPlayer)
            // so that the former can render in the UI the video frames produced in the background by the latter.
            //videoPlayerElement.SetMediaPlayer(_videoPlayer);

            //// Uncomment to initialize local transceivers and tracks.
            //if (Utils.IsFirstInstance())
            //{
            //    // Add transceivers
            //    var transceiverA = AddTransceiver(MediaKind.Audio,
            //        new TransceiverInitSettings { Name = "audio_transceiver" });

            //    var transceiverV = AddTransceiver(MediaKind.Video,
            //        new TransceiverInitSettings { Name = "video_transceiver", });

            //    // Add audio track
            //    var sourceA = await DeviceAudioTrackSource.CreateAsync(new LocalAudioDeviceInitConfig());
            //    var trackA = LocalAudioTrack.CreateFromSource(sourceA,
            //        new LocalAudioTrackInitConfig { trackName = "local_audio" });
            //    AddAudioTrack(trackA, "Audio Device");

            //    // Add the track to the transceiver.
            //    {
            //        var transceiverVM = Transceivers.First(t => t.Transceiver == transceiverA);
            //        var trackVM = transceiverVM.AvailableSenders.Last();
            //        transceiverVM.Sender = trackVM;
            //    }

            //    // Add video track
            //    var sourceV = await DeviceVideoTrackSource.CreateAsync(
            //        new LocalVideoDeviceInitConfig
            //        {
            //            videoDevice = new VideoCaptureDevice
            //            {
            //                id = @"<insert_device_id>"
            //            },
            //            videoProfileId = string.Empty,
            //            width = 640,
            //            height = 480,
            //            framerate = 30
            //        });
            //    // Crate the track
            //    var trackV = LocalVideoTrack.CreateFromSource(sourceV,
            //        new LocalVideoTrackInitConfig { trackName = "local_video" });
            //    AddVideoTrack(trackV, "Video Device");

            //    // Add the track to the transceiver.
            //    {
            //        var transceiverVM = Transceivers.First(t => t.Transceiver == transceiverV);
            //        var trackVM = transceiverVM.AvailableSenders.Last();
            //        transceiverVM.Sender = trackVM;
            //    }
            //}
        }
コード例 #20
0
        public async Task InBand()
        {
            // Setup
            var config = new PeerConnectionConfiguration();
            var pc1    = new PeerConnection();
            var pc2    = new PeerConnection();
            await pc1.InitializeAsync(config);

            await pc2.InitializeAsync(config);

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

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

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

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

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

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

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

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

            // Clean-up
            pc1.Close();
            pc1.Dispose();
            pc2.Close();
            pc2.Dispose();
        }
コード例 #21
0
        static async Task Main(string[] args)
        {
            Transceiver      audioTransceiver = null;
            Transceiver      videoTransceiver = null;
            AudioTrackSource audioTrackSource = null;
            VideoTrackSource videoTrackSource = null;
            LocalAudioTrack  localAudioTrack  = null;
            LocalVideoTrack  localVideoTrack  = null;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            Console.WriteLine("Program termined.");

            localAudioTrack.Dispose();
            localVideoTrack.Dispose();
            audioTrackSource.Dispose();
            videoTrackSource.Dispose();
        }
コード例 #22
0
        static async Task Main(string[] args)
        {
            DataChannel dataChannel = null;

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

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

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

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

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

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

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

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

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

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

                ConsoleKeyInfo key;

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

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

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

            await _peerConnection.InitializeAsync(config);

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

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

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


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

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

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

            await _hubConnection.StartAsync();

            await _hubConnection.InvokeAsync("JoinRoom", SignallerConstants.RoomName);
        }
コード例 #24
0
        //Loaded-EventHandler of ui: executes after ui-loading
        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            //Request access to mic and cam
            MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();

            settings.StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo;

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

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

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

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

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

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

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

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

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

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

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

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

                case NodeDssSignaler.Message.WireMessageType.Ice:
                    string[] parts = msg.Data.Split(new string[] { msg.IceDataSeparator }, StringSplitOptions.RemoveEmptyEntries);
                    //Changing order of parts
                    string sdpMid        = parts[2];
                    int    sdpMlineindex = int.Parse(parts[1]);
                    string candidate     = parts[0];
                    peerConnection.AddIceCandidate(sdpMid, sdpMlineindex, candidate);
                    break;
                }
            };
            signaler.StartPollingAsync();
        }
コード例 #25
0
        private static async void MessageReceived(WebRtcSession session, string msg)
        {
            Console.WriteLine($"web socket recv: {msg.Length} bytes");

            JObject jsonMsg = JObject.Parse(msg);

            if ((string)jsonMsg["type"] == "ice")
            {
                Console.WriteLine($"Adding remote ICE candidate {msg}.");

                while (!session.pc.Initialized)
                {
                    // This delay is needed due to an initialise bug in the Microsoft.MixedReality.WebRTC
                    // nuget packages up to version 0.2.3. On master awaiting pc.InitializeAsync does end
                    // up with the pc object being ready.
                    Console.WriteLine("Sleeping for 1s while peer connection is initialising...");
                    await Task.Delay(1000);
                }

                session.pc.AddIceCandidate((string)jsonMsg["sdpMLineindex"], (int)jsonMsg["sdpMid"], (string)jsonMsg["candidate"]);
            }
            else if ((string)jsonMsg["type"] == "sdp")
            {
                Console.WriteLine("Received remote peer SDP offer.");

                var config = new PeerConnectionConfiguration();

                session.pc.IceCandidateReadytoSend += (string candidate, int sdpMlineindex, string sdpMid) =>
                {
                    Console.WriteLine($"Sending ice candidate: {candidate}");
                    JObject iceCandidate = new JObject {
                        { "type", "ice" },
                        { "candidate", candidate },
                        { "sdpMLineindex", sdpMlineindex },
                        { "sdpMid", sdpMid }
                    };
                    session.Context.WebSocket.Send(iceCandidate.ToString());
                };

                session.pc.IceStateChanged += (newState) =>
                {
                    Console.WriteLine($"ice connection state changed to {newState}.");
                };

                session.pc.LocalSdpReadytoSend += (string type, string sdp) =>
                {
                    Console.WriteLine($"SDP answer ready, sending to remote peer.");

                    // Send our SDP answer to the remote peer.
                    JObject sdpAnswer = new JObject {
                        { "type", "sdp" },
                        { "answer", sdp }
                    };
                    session.Context.WebSocket.Send(sdpAnswer.ToString());
                };

                await session.pc.InitializeAsync(config).ContinueWith((t) =>
                {
                    session.pc.SetRemoteDescription("offer", (string)jsonMsg["offer"]);

                    if (!session.pc.CreateAnswer())
                    {
                        Console.WriteLine("Failed to create peer connection answer, closing peer connection.");
                        session.pc.Close();
                        session.Context.WebSocket.Close();
                    }
                });

                // Create a new form to display the video feed from the WebRTC peer.
                var form = new Form();
                form.AutoSize = true;
                form.BackgroundImageLayout = ImageLayout.Center;
                PictureBox picBox = null;

                form.HandleDestroyed += (object sender, EventArgs e) =>
                {
                    Console.WriteLine("Form closed, closing peer connection.");
                    session.pc.Close();
                    session.Context.WebSocket.Close();
                };

                session.pc.ARGBRemoteVideoFrameReady += (frame) =>
                {
                    var width  = frame.width;
                    var height = frame.height;
                    var stride = frame.stride;
                    var data   = frame.data;

                    if (picBox == null)
                    {
                        picBox = new PictureBox
                        {
                            Size     = new Size((int)width, (int)height),
                            Location = new Point(0, 0),
                            Visible  = true
                        };
                        form.BeginInvoke(new Action(() => { form.Controls.Add(picBox); }));
                    }

                    form.BeginInvoke(new Action(() =>
                    {
                        System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap((int)width, (int)height, (int)stride, System.Drawing.Imaging.PixelFormat.Format32bppArgb, data);
                        picBox.Image = bmpImage;
                    }));
                };

                Application.EnableVisualStyles();
                Application.Run(form);
            }
        }
コード例 #26
0
        public void SetupConnection()
        {
            Assert.AreEqual(0, Library.ReportLiveObjects());

            // Create the 2 peers
            var config = new PeerConnectionConfiguration();

            config.SdpSemantic = sdpSemantic_;
            pc1_ = new PeerConnection();
            pc2_ = new PeerConnection();
            pc1_.InitializeAsync(config).Wait(); // cannot use async/await in OneTimeSetUp
            pc2_.InitializeAsync(config).Wait();

            exchangePending_   = false;
            exchangeCompleted_ = new ManualResetEventSlim(false);

            // Allocate callback events
            connectedEvent1_          = new ManualResetEventSlim(false);
            connectedEvent2_          = new ManualResetEventSlim(false);
            remoteDescAppliedEvent1_  = new ManualResetEventSlim(false);
            remoteDescAppliedEvent2_  = new ManualResetEventSlim(false);
            iceConnectedEvent1_       = new ManualResetEventSlim(false);
            iceConnectedEvent2_       = new ManualResetEventSlim(false);
            renegotiationEvent1_      = new ManualResetEventSlim(false);
            renegotiationEvent2_      = new ManualResetEventSlim(false);
            dataChannelAddedEvent1_   = new ManualResetEventSlim(false);
            dataChannelAddedEvent2_   = new ManualResetEventSlim(false);
            dataChannelRemovedEvent1_ = new ManualResetEventSlim(false);
            dataChannelRemovedEvent2_ = new ManualResetEventSlim(false);
            audioTrackAddedEvent1_    = new ManualResetEventSlim(false);
            audioTrackAddedEvent2_    = new ManualResetEventSlim(false);
            audioTrackRemovedEvent1_  = new ManualResetEventSlim(false);
            audioTrackRemovedEvent2_  = new ManualResetEventSlim(false);
            videoTrackAddedEvent1_    = new ManualResetEventSlim(false);
            videoTrackAddedEvent2_    = new ManualResetEventSlim(false);
            videoTrackRemovedEvent1_  = new ManualResetEventSlim(false);
            videoTrackRemovedEvent2_  = new ManualResetEventSlim(false);

            // Connect all signals
            pc1_.Connected               += OnConnected1;
            pc2_.Connected               += OnConnected2;
            pc1_.LocalSdpReadytoSend     += OnLocalSdpReady1;
            pc2_.LocalSdpReadytoSend     += OnLocalSdpReady2;
            pc1_.IceCandidateReadytoSend += OnIceCandidateReadytoSend1;
            pc2_.IceCandidateReadytoSend += OnIceCandidateReadytoSend2;
            pc1_.IceStateChanged         += OnIceStateChanged1;
            pc2_.IceStateChanged         += OnIceStateChanged2;
            pc1_.RenegotiationNeeded     += OnRenegotiationNeeded1;
            pc2_.RenegotiationNeeded     += OnRenegotiationNeeded2;
            pc1_.DataChannelAdded        += OnDataChannelAdded1;
            pc2_.DataChannelAdded        += OnDataChannelAdded2;
            pc1_.DataChannelRemoved      += OnDataChannelRemoved1;
            pc2_.DataChannelRemoved      += OnDataChannelRemoved2;
            pc1_.AudioTrackAdded         += OnAudioTrackAdded1;
            pc2_.AudioTrackAdded         += OnAudioTrackAdded2;
            pc1_.AudioTrackRemoved       += OnAudioTrackRemoved1;
            pc2_.AudioTrackRemoved       += OnAudioTrackRemoved2;
            pc1_.VideoTrackAdded         += OnVideoTrackAdded1;
            pc2_.VideoTrackAdded         += OnVideoTrackAdded2;
            pc1_.VideoTrackRemoved       += OnVideoTrackRemoved1;
            pc2_.VideoTrackRemoved       += OnVideoTrackRemoved2;

            // Enable automatic renegotiation
            suspendOffer1_ = false;
            suspendOffer2_ = false;
        }
コード例 #27
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.");
        }
コード例 #28
0
        private static async void MessageReceived(WebSocketContext context, string msg)
        {
            Console.WriteLine($"websocket recv: {msg}");

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

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

            // Create a new form to display the video feed from the WebRTC peer.
            var form = new Form();

            form.AutoSize = true;
            form.BackgroundImageLayout = ImageLayout.Center;
            PictureBox picBox = null;

            pc.SetRemoteDescription("offer", msg);

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

                // Send our SDP answer to the remote peer.
                context.WebSocket.Send(sdp);
            };

            if (pc.CreateAnswer())
            {
                Console.WriteLine("Peer connection answer successfully created.");
            }
            else
            {
                Console.WriteLine("Failed to create peer connection answer.");
                pc.Close();
            }

            pc.ARGBRemoteVideoFrameReady += (frame) =>
            {
                var width  = frame.width;
                var height = frame.height;
                var stride = frame.stride;
                var data   = frame.data;

                if (picBox == null)
                {
                    picBox = new PictureBox
                    {
                        Size     = new Size((int)width, (int)height),
                        Location = new Point(0, 0),
                        Visible  = true
                    };
                    form.BeginInvoke(new Action(() => { form.Controls.Add(picBox); }));
                }

                form.BeginInvoke(new Action(() =>
                {
                    System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap((int)width, (int)height, (int)stride, System.Drawing.Imaging.PixelFormat.Format32bppArgb, data);
                    picBox.Image = bmpImage;
                }));
            };

            Application.EnableVisualStyles();
            Application.Run(form);
        }
コード例 #29
0
 public static extern uint PeerConnection_Create(PeerConnectionConfiguration config, IntPtr peer,
                                                 out PeerConnectionHandle peerHandleOut);
コード例 #30
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 + "-");
        }