Ejemplo n.º 1
0
        public void EnumVideoFormats()
        {
            PeerConnection.GetVideoCaptureDevicesAsync().ContinueWith((enumDeviceTask) =>
            {
                Assert.IsNull(enumDeviceTask.Exception);
                List <VideoCaptureDevice> devices = enumDeviceTask.Result;
                if (devices.Count == 0)
                {
                    Assert.Inconclusive("Host device has no available video capture device.");
                }

                foreach (var device in devices)
                {
                    PeerConnection.GetVideoCaptureFormatsAsync(device.id).ContinueWith((enumFormatTask) =>
                    {
                        Assert.IsNull(enumFormatTask.Exception);
                        List <VideoCaptureFormat> formats = enumFormatTask.Result;
                        foreach (var format in formats)
                        {
                            Assert.That(format.width, Is.GreaterThan(0));
                            Assert.That(format.height, Is.GreaterThan(0));
                            Assert.That(format.framerate, Is.GreaterThan(0.0));
                        }
                    });
                }
            });
        }
Ejemplo n.º 2
0
 public void EnumVideoDevices()
 {
     PeerConnection.GetVideoCaptureDevicesAsync().ContinueWith((enumTask) =>
     {
         Assert.IsNull(enumTask.Exception);
         List <VideoCaptureDevice> devices = enumTask.Result;
         foreach (var device in devices)
         {
             Assert.That(device.id.Length, Is.GreaterThan(0));
             Assert.That(device.name.Length, Is.GreaterThan(0));
         }
     });
 }
Ejemplo n.º 3
0
        public async Task RefreshVideoCaptureDevicesAsync()
        {
            Logger.Log($"Refreshing list of video capture devices");

            ErrorMessage = null;
            try
            {
                await RequestMediaAccessAsync(StreamingCaptureMode.Video);
            }
            catch (UnauthorizedAccessException uae)
            {
                ErrorMessage = "This application is not authorized to access the local camera device. Change permission settings and restart the application.";
                throw uae;
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
                throw ex;
            }

            // Populate the list of video capture devices (webcams).
            // On UWP this uses internally the API:
            //   Devices.Enumeration.DeviceInformation.FindAllAsync(VideoCapture)
            // Note that there's no API to pass a given device to WebRTC,
            // so there's no way to monitor and update that list if a device
            // gets plugged or unplugged. Even using DeviceInformation.CreateWatcher()
            // would yield some devices that might become unavailable by the time
            // WebRTC internally opens the video capture device.
            // This is more for demo purpose here because using the UWP API is nicer.
            var devices = await PeerConnection.GetVideoCaptureDevicesAsync();

            var deviceList = new CollectionViewModel <VideoCaptureDeviceInfo>();

            foreach (var device in devices)
            {
                Logger.Log($"Found video capture device: id={device.id} name={device.name}");
                deviceList.Add(new VideoCaptureDeviceInfo(id: device.id, displayName: device.name));
            }
            VideoCaptureDevices = deviceList;

            // Auto-select first device for convenience
            VideoCaptureDevices.SelectFirstItemIfAny();
        }
Ejemplo n.º 4
0
        static async Task Main(string[] args)
        {
            Transceiver      audioTransceiver = null;
            Transceiver      videoTransceiver = null;
            AudioTrackSource audioTrackSource = null;
            VideoTrackSource videoTrackSource = null;
            LocalAudioTrack  localAudioTrack  = null;
            LocalVideoTrack  localVideoTrack  = null;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            Console.WriteLine("Program termined.");

            localAudioTrack.Dispose();
            localVideoTrack.Dispose();
            audioTrackSource.Dispose();
            videoTrackSource.Dispose();
        }
Ejemplo n.º 5
0
        private async void OnLoaded(object sender, RoutedEventArgs e)
        {
            // Request access to microphone and camera
            var settings = new MediaCaptureInitializationSettings();

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

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

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

            _peerConnection = new PeerConnection();


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

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

            await _peerConnection.AddLocalAudioTrackAsync();

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

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



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

                _peerConnection.I420RemoteVideoFrameReady += Peer_RemoteI420AFrameReady;

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

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

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

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

                _signaler.StartPollingAsync();
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            Console.WriteLine("Program termined.");
        }
Ejemplo n.º 7
0
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            LogMessage("Initializing the WebRTC native plugin...");

            // Populate the list of video capture devices (webcams).
            // On UWP this uses internally the API:
            //   Devices.Enumeration.DeviceInformation.FindAllAsync(VideoCapture)
            // Note that there's no API to pass a given device to WebRTC,
            // so there's no way to monitor and update that list if a device
            // gets plugged or unplugged. Even using DeviceInformation.CreateWatcher()
            // would yield some devices that might become unavailable by the time
            // WebRTC internally opens the video capture device.
            // This is more for demo purpose here because using the UWP API is nicer.
            {
                // Use a local list accessible from a background thread
                List <VideoCaptureDevice> vcds = new List <VideoCaptureDevice>(4);
                PeerConnection.GetVideoCaptureDevicesAsync().ContinueWith((prevTask) =>
                {
                    if (prevTask.Exception != null)
                    {
                        throw prevTask.Exception;
                    }

                    var devices   = prevTask.Result;
                    vcds.Capacity = devices.Count;
                    foreach (var device in devices)
                    {
                        vcds.Add(new VideoCaptureDevice()
                        {
                            Id          = device.id,
                            DisplayName = device.name,
                            Symbol      = Symbol.Video
                        });
                    }

                    // Assign on main UI thread because of XAML binding; otherwise it fails.
                    RunOnMainThread(() =>
                    {
                        VideoCaptureDevices.Clear();
                        foreach (var vcd in vcds)
                        {
                            VideoCaptureDevices.Add(vcd);
                            LogMessage($"VCD id={vcd.Id} name={vcd.DisplayName}");
                        }
                    });
                });
            }

            //localVideo.TransportControls = localVideoControls;

            PluginInitialized = false;

            // Assign STUN server(s) before calling InitializeAsync()
            _peerConnection.Servers.Clear(); // We use only one server in this demo
            _peerConnection.Servers.Add("stun:" + stunServer.Text);

            // Ensure that the UWP app was authorized to capture audio (cap:microphone)
            // and video (cap:webcam), otherwise the native plugin will fail.
            try
            {
                MediaCapture mediaAccessRequester = new MediaCapture();
                var          mediaSettings        = new MediaCaptureInitializationSettings
                {
                    AudioDeviceId        = "",
                    VideoDeviceId        = "",
                    StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
                    PhotoCaptureSource   = PhotoCaptureSource.VideoPreview
                };
                var uiThreadScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                mediaAccessRequester.InitializeAsync(mediaSettings).AsTask()
                .ContinueWith((accessTask) =>
                {
                    if (accessTask.Exception != null)
                    {
                        LogMessage($"Access to A/V denied, check app permissions: {accessTask.Exception.Message}");
                        throw accessTask.Exception;
                    }
                    _peerConnection.InitializeAsync().ContinueWith((initTask) =>
                    {
                        if (initTask.Exception != null)
                        {
                            LogMessage($"WebRTC native plugin init failed: {initTask.Exception.Message}");
                            throw initTask.Exception;
                        }
                        OnPluginPostInit();
                    }, uiThreadScheduler);     // run task on caller (UI) thread
                });
            }
            //< TODO - This below shouldn't do anything since exceptions are caught and stored inside Task.Exception...
            catch (UnauthorizedAccessException uae)
            {
                LogMessage("Access to A/V denied: " + uae.Message);
            }
            catch (Exception ex)
            {
                if (ex.InnerException is UnauthorizedAccessException uae)
                {
                    LogMessage("Access to A/V denied: " + uae.Message);
                }
                else
                {
                    LogMessage("Failed to initialize A/V with unknown exception: " + ex.Message);
                }
            }
        }
        //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();
        }