Пример #1
0
        public void StartCapture(IntPtr hWnd, Device device, Factory factory)
        {
            var capturePicker = new GraphicsCapturePicker();

            // ReSharper disable once PossibleInvalidCastException
            // ReSharper disable once SuspiciousTypeConversion.Global
            var initializer = (IInitializeWithWindow)(object)capturePicker;

            initializer.Initialize(hWnd);

            _captureItem = capturePicker.PickSingleItemAsync().AsTask().Result;
            if (_captureItem == null)
            {
                return;
            }

            _captureItem.Closed += CaptureItemOnClosed;

            var hr = NativeMethods.CreateDirect3D11DeviceFromDXGIDevice(device.NativePointer, out var pUnknown);

            if (hr != 0)
            {
                StopCapture();
                return;
            }

            var winrtDevice = (IDirect3DDevice)Marshal.GetObjectForIUnknown(pUnknown);

            Marshal.Release(pUnknown);

            _captureFramePool = Direct3D11CaptureFramePool.Create(winrtDevice, DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, _captureItem.Size);
            _captureSession   = _captureFramePool.CreateCaptureSession(_captureItem);
            _captureSession.StartCapture();
            IsCapturing = true;
        }
Пример #2
0
        private async void RecordButton_Click(object sender, RoutedEventArgs e)
        {
            var button = (AppBarToggleButton)sender;

            if (button.IsChecked.Value)
            {
                var picker = new GraphicsCapturePicker();
                var item   = await picker.PickSingleItemAsync();

                if (item == null)
                {
                    button.IsChecked = false;
                    return;
                }

                var file = await PickVideoAsync();

                if (file == null)
                {
                    button.IsChecked = false;
                    return;
                }

                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item))
                    {
                        await _encoder.EncodeAsync(stream);
                    }
            }
            else
            {
                _encoder?.Dispose();
            }
        }
Пример #3
0
        public async Task <GraphicsCaptureItemWrapper> UserSelectAsync(IntPtr hwnd)
        {
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(hwnd);
            var item = await picker.PickSingleItemAsync();

            return(item != null ? new GraphicsCaptureItemWrapper(item, "UserSelect") : null);
        }
Пример #4
0
        public async Task StartAsync()
        {
            var item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                var capture = new BasicCapture(device, item);
                this.currentCapture = capture;

                capture.StartCapture();
            }
        }
Пример #5
0
        private async Task StartPickerCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(hwnd);
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                sample.StartCaptureFromItem(item);
            }
        }
Пример #6
0
        public async Task StartCaptureAsync()
        {
            // 让用户选择哪个应用
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // 如果用户有选择一个应用那么这个属性不为空
            if (item != null)
            {
                StartCaptureInternal(item);
            }
        }
Пример #7
0
        public async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                _captureFolder = await _setupCpatureFolder();

                _startCaptureInternal(item);
            }
        }
Пример #8
0
        public async Task <VoipVideoCapture> ToggleCapturingAsync(VoipCaptureType type)
        {
            void Disable()
            {
                if (_capturer != null)
                {
                    _capturer.SetOutput(null);
                    _manager.SetVideoCapture(null);

                    _capturer.Dispose();
                    _capturer = null;
                }
            }

            if (type == VoipCaptureType.None)
            {
                Disable();
            }
            else if (type == VoipCaptureType.Video && _capturer is not VoipVideoCapture)
            {
                Disable();

                if (_manager == null)
                {
                    return(null);
                }

                _capturer = new VoipVideoCapture(await _videoWatcher.GetAndUpdateAsync());
                _manager?.SetVideoCapture(_capturer);
            }
            else if (type == VoipCaptureType.Screencast && _capturer is not VoipScreenCapture)
            {
                Disable();

                if (_manager == null || !GraphicsCaptureSession.IsSupported())
                {
                    return(null);
                }

                var picker = new GraphicsCapturePicker();
                var item   = await picker.PickSingleItemAsync();

                if (item == null || _manager == null)
                {
                    return(null);
                }

                _capturer = new VoipScreenCapture(item);
                _manager?.SetVideoCapture(_capturer);
            }

            return(_capturer);
        }
Пример #9
0
        private async Task StartRecordingAsync()
        {
            GraphicsCapturePicker pick = new GraphicsCapturePicker();
            var recordedfield          = await pick.PickSingleItemAsync();

            CoreWindow window = CoreApplication.MainView.CoreWindow;

            await window.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() =>
            {
                await new ScreenRecord().Record(recordedfield);
            });
        }
Пример #10
0
        public async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                StartCaptureInternal(item);
            }
        }
Пример #11
0
        private async void CaptureButton_Click(object sender, RoutedEventArgs e)
        {
            StopCapture();

            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                StartCapture(item);
            }
        }
        public async Task CaptureScreenshotAsync(string filename)
        {
            this.fileName = filename;
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                await StartCaptureInternal(item);
            }
        }
Пример #13
0
        private async Task StartPickerCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(_hwnd);
            var item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                var dc = this.DataContext as MainViewModel;
                dc.TargetName.Value = item.DisplayName;
                StartCapture(item);
            }
        }
Пример #14
0
        public async Task PickScreen()
        {
            GraphicsCapturePicker picker = new GraphicsCapturePicker();
            GraphicsCaptureItem   item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                if (simpleRecorder != null)
                {
                    simpleRecorder.gcitem = item;
                    ScreenTextBox.Text    = item.DisplayName;
                }
            }
        }
Пример #15
0
        private async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                _capture = new Capture(_device, item);

                var surface = _capture.CreateSurface(_compositor);
                _brush.Surface = surface;

                _capture.StartCapture();
            }
        }
        public async Task StartCaptureAsync()
        {
            _canvasDevice = CanvasDevice.GetSharedDevice();
            // The GraphicsCapturePicker follows the same pattern the
            // file pickers do.
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                StartCaptureInternal(item);
            }
        }
Пример #17
0
        public async Task StartCaptureAsync()
        {
            composition = new MediaComposition();
            // The GraphicsCapturePicker follows the same pattern the
            // file pickers do.
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            // The item may be null if the user dismissed the
            // control without making a selection or hit Cancel.
            if (item != null)
            {
                StopButton.Visibility = Visibility.Visible;
                // We'll define this method later in the document.
                StartCaptureInternal(item);
            }
        }
Пример #18
0
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                StartPreview(item);
            }
            else
            {
                StopPreview();
            }



            _item = item;
        }
Пример #19
0
        private async Task StartRecording()
        {
            Debug.Assert(!IsRecording);

            var pick        = new GraphicsCapturePicker();
            var captureItem = await pick.PickSingleItemAsync();

            if (captureItem != null)
            {
                _recorderOutput = ApplicationData.Current.TemporaryFolder;

                await ClearFolder(_recorderOutput);

                _sw.Restart();
                _elapsedUpdateTimer.Start();

                _recorder.Start(captureItem, _recorderOutput);
            }

            IsRecording = true;
        }
Пример #20
0
        public async Task StartCaptureAsyncInternal()
        {
            Logger.Debug("Screen", "StartCaptureAsyncInternal");

            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item == null)
            {
                return;
            }

            StopCaptureInternal();

            this.item     = item;
            this.lastSize = item.Size;

            screenCaptureTask = CreateScreenCaptureTask();
            screenCaptureTask.Start();

            if (canvasDevice == null)
            {
                canvasDevice = new CanvasDevice();
            }

            framePool = Direct3D11CaptureFramePool.Create(
                canvasDevice,
                DirectXPixelFormat.B8G8R8A8UIntNormalized,
                2,
                item.Size);

            framePool.FrameArrived += FramePool_FrameArrived;
            item.Closed            += (s, a) =>
            {
                StopCaptureInternal();
            };
            session = framePool.CreateCaptureSession(item);
            session.StartCapture();
        }
Пример #21
0
        public async Task StartCaptureAsync()
        {
            var picker = new GraphicsCapturePicker();
            GraphicsCaptureItem item;

            if (saveitem == null)
            {
                item = await picker.PickSingleItemAsync();
            }
            else
            {
                item = saveitem;
            }
            if (item != null)
            {
                lnd.DisplayHeight = item.Size.Height;
                lnd.DisplayWidth  = item.Size.Width;
                lnd.Update();
                Update();
                WriteSittings();
                StartCaptureInternal(item);
            }
        }
Пример #22
0
        private async Task PrepareCapture()
        {
            lbInfo.Content = "상태 : 윈도우 선택중";
            var picker = new GraphicsCapturePicker();

            picker.SetWindow(hwnd);
            GraphicsCaptureItem item = await picker.PickSingleItemAsync();

            if (item != null)
            {
                IntPtr hWnd = GethWnd(item.DisplayName);

                if (hWnd == IntPtr.Zero)
                {
                    if (MessageBox.Show("해당 윈도우는 캡쳐할 수 없습니다" + System.Environment.NewLine + "윈도우가 활성화 되어 있는지 확인해 주세요", "오류", MessageBoxButton.OK) == MessageBoxResult.OK)
                    {
                        Close();
                    }
                }
                else
                {
                    item.Closed += (s, a) =>
                    {
                        StopCapture();
                    };
                    sample.StartCaptureFromItem(item, hWnd);
                    callback();

                    lbInfo.Content = "상태 : 캡쳐 중 - " + item.DisplayName;
                }
            }
            else
            {
                Close();
            }
        }
        private async Task SetupEncoding()
        {
            if (!GraphicsCaptureSession.IsSupported())
            {
                // Show message to user that screen capture is unsupported
                return;
            }

            // Create the D3D device and SharpDX device
            if (_device == null)
            {
                _device = Direct3D11Helpers.CreateD3DDevice();
            }
            if (_sharpDxD3dDevice == null)
            {
                _sharpDxD3dDevice = Direct3D11Helpers.CreateSharpDXDevice(_device);
            }



            try
            {
                // Let the user pick an item to capture
                var picker = new GraphicsCapturePicker();
                _captureItem = await picker.PickSingleItemAsync();

                if (_captureItem == null)
                {
                    return;
                }

                // Initialize a blank texture and render target view for copying frames, using the same size as the capture item
                _composeTexture          = Direct3D11Helpers.InitializeComposeTexture(_sharpDxD3dDevice, _captureItem.Size);
                _composeRenderTargetView = new SharpDX.Direct3D11.RenderTargetView(_sharpDxD3dDevice, _composeTexture);

                // This example encodes video using the item's actual size.
                var width  = (uint)_captureItem.Size.Width;
                var height = (uint)_captureItem.Size.Height;

                // Make sure the dimensions are are even. Required by some encoders.
                width  = (width % 2 == 0) ? width : width + 1;
                height = (height % 2 == 0) ? height : height + 1;


                var  temp      = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);
                var  bitrate   = temp.Video.Bitrate;
                uint framerate = 30;

                _encodingProfile = new MediaEncodingProfile();
                _encodingProfile.Container.Subtype                  = "MPEG4";
                _encodingProfile.Video.Subtype                      = "H264";
                _encodingProfile.Video.Width                        = width;
                _encodingProfile.Video.Height                       = height;
                _encodingProfile.Video.Bitrate                      = bitrate;
                _encodingProfile.Video.FrameRate.Numerator          = framerate;
                _encodingProfile.Video.FrameRate.Denominator        = 1;
                _encodingProfile.Video.PixelAspectRatio.Numerator   = 1;
                _encodingProfile.Video.PixelAspectRatio.Denominator = 1;

                var videoProperties = VideoEncodingProperties.CreateUncompressed(MediaEncodingSubtypes.Bgra8, width, height);
                _videoDescriptor = new VideoStreamDescriptor(videoProperties);

                // Create our MediaStreamSource
                _mediaStreamSource                  = new MediaStreamSource(_videoDescriptor);
                _mediaStreamSource.BufferTime       = TimeSpan.FromSeconds(0);
                _mediaStreamSource.Starting        += OnMediaStreamSourceStarting;
                _mediaStreamSource.SampleRequested += OnMediaStreamSourceSampleRequested;

                // Create our transcoder
                _transcoder = new MediaTranscoder();
                _transcoder.HardwareAccelerationEnabled = true;

                using (var stream = new InMemoryRandomAccessStream())
                    await EncodeAsync(stream);
            }
            catch (Exception ex)
            {
                return;
            }
        }
Пример #24
0
        private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            var button = (ToggleButton)sender;

            // Get our encoder properties
            var frameRate     = uint.Parse(((string)FrameRateComboBox.SelectedItem).Replace("fps", ""));
            var quality       = (VideoEncodingQuality)Enum.Parse(typeof(VideoEncodingQuality), (string)QualityComboBox.SelectedItem, false);
            var useSourceSize = UseCaptureItemSizeCheckBox.IsChecked.Value;

            var temp    = MediaEncodingProfile.CreateMp4(quality);
            var bitrate = temp.Video.Bitrate;
            var width   = temp.Video.Width;
            var height  = temp.Video.Height;

            // Get our capture item
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item == null)
            {
                button.IsChecked = false;
                return;
            }

            // Use the capture item's size for the encoding if desired
            if (useSourceSize)
            {
                width  = (uint)item.Size.Width;
                height = (uint)item.Size.Height;

                // Even if we're using the capture item's real size,
                // we still want to make sure the numbers are even.
                // Some encoders get mad if you give them odd numbers.
                width  = EnsureEven(width);
                height = EnsureEven(height);
            }

            // Find a place to put our vidoe for now
            var file = await GetTempFileAsync();

            // Tell the user we've started recording
            MainTextBlock.Text = "● rec";
            var originalBrush = MainTextBlock.Foreground;

            MainTextBlock.Foreground        = new SolidColorBrush(Colors.Red);
            MainProgressBar.IsIndeterminate = true;


            //await StartCaptureAsync();

            // Kick off the encoding
            try
            {
                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item, _surface))
                    {
                        await _encoder.EncodeAsync(
                            stream,
                            width, height, bitrate,
                            frameRate);
                    }
                MainTextBlock.Foreground = originalBrush;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex);

                var message = GetMessageForHResult(ex.HResult);
                if (message == null)
                {
                    message = $"Uh-oh! Something went wrong!\n0x{ex.HResult:X8} - {ex.Message}";
                }
                var dialog = new MessageDialog(
                    message,
                    "Recording failed");

                await dialog.ShowAsync();

                button.IsChecked                = false;
                MainTextBlock.Text              = "failure";
                MainTextBlock.Foreground        = originalBrush;
                MainProgressBar.IsIndeterminate = false;
                return;
            }

            // At this point the encoding has finished,
            // tell the user we're now saving
            MainTextBlock.Text = "saving...";

            // Ask the user where they'd like the video to live
            var newFile = await PickVideoAsync();

            if (newFile == null)
            {
                // User decided they didn't want it
                // Throw out the encoded video
                button.IsChecked   = false;
                MainTextBlock.Text = "canceled";
                MainProgressBar.IsIndeterminate = false;
                await file.DeleteAsync();

                return;
            }
            // Move our vidoe to its new home
            await file.MoveAndReplaceAsync(newFile);

            // Tell the user we're done
            button.IsChecked   = false;
            MainTextBlock.Text = "done";
            MainProgressBar.IsIndeterminate = false;

            // Open the final product
            await Launcher.LaunchFileAsync(newFile);
        }
        private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            var button = (ToggleButton)sender;
            var folder = await KnownFolders.VideosLibrary.TryGetItemAsync("Fluent Screen Recorder");

            // Get our encoder properties
            var frameRateItem  = (FrameRateItem)FrameRateComboBox.SelectedItem;
            var resolutionItem = (ResolutionItem)ResolutionComboBox.SelectedItem;
            var bitrateItem    = (BitrateItem)BitrateComboBox.SelectedItem;


            MediaCapture mediaCapture = null;

            if (AudioToggleSwitch.IsOn)
            {
                loopbackAudioCapture = new LoopbackAudioCapture(MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default));
                loopbackAudioCapture.BufferReadyDelegate = LoopbackBufferReady;
                BufferList.Clear();
            }
            else if (ExtAudioToggleSwitch.IsOn)
            {
                if (await IsMicAllowed())
                {
                    mediaCapture = new MediaCapture();
                    MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings
                    {
                        StreamingCaptureMode = StreamingCaptureMode.Audio
                    };
                    await mediaCapture.InitializeAsync(settings);

                    var tempfolder = ApplicationData.Current.TemporaryFolder;
                    var name       = DateTime.Now.ToString("yyyy-MM-dd-HHmmss");
                    micFile = await tempfolder.CreateFileAsync($"{name}.mp3");
                }
                else
                {
                    ContentDialog errorDialog = new ContentDialog
                    {
                        Title           = "Recording failed",
                        Content         = "Permission to use microphone was not given", //TODO: fix this non-english horror
                        CloseButtonText = "OK"
                    };
                    await errorDialog.ShowAsync();

                    return;
                }
            }

            var width         = resolutionItem.Resolution.Width;
            var height        = resolutionItem.Resolution.Height;
            var bitrate       = bitrateItem.Bitrate;
            var frameRate     = frameRateItem.FrameRate;
            var useSourceSize = resolutionItem.IsZero();
            var picker        = new GraphicsCapturePicker();
            var item          = await picker.PickSingleItemAsync();

            if (item == null)
            {
                button.IsChecked = false;
                return;
            }
            if (useSourceSize)
            {
                resolutionItem.IsZero();
                width  = (uint)item.Size.Width;
                height = (uint)item.Size.Height;

                // Even if we're using the capture item's real size,
                // we still want to make sure the numbers are even.
                // Some encoders get mad if you give them odd numbers.
                width  = EnsureEven(width);
                height = EnsureEven(height);
            }


            // Put videos in the temp folder
            var tempFile = await GetTempFileAsync();

            _tempFile = tempFile;

            // Tell the user we've started recording
            SecondColumn.Width = new GridLength(0);
            ThirdColumn.Width  = new GridLength(0);



            visual = ElementCompositionPreview.GetElementVisual(Ellipse);
            var animation = visual.Compositor.CreateScalarKeyFrameAnimation();

            animation.InsertKeyFrame(0, 1);
            animation.InsertKeyFrame(1, 0);
            animation.Duration          = TimeSpan.FromMilliseconds(1500);
            animation.IterationBehavior = AnimationIterationBehavior.Forever;
            visual.StartAnimation("Opacity", animation);

            RecordIcon.Visibility = Visibility.Collapsed;
            StopIcon.Visibility   = Visibility.Visible;
            Ellipse.Visibility    = Visibility.Visible;
            toolTip         = new ToolTip();
            toolTip.Content = Strings.Resources.RecordingStop;
            ToolTipService.SetToolTip(MainButton, toolTip);
            AutomationProperties.SetName(MainButton, Strings.Resources.RecordingStop);
            MainTextBlock.Text = Strings.Resources.Recording;
            var originalBrush = MainTextBlock.Foreground;

            MainTextBlock.Foreground = new SolidColorBrush(Colors.Red);
            lockAdaptiveUI           = true;

            // Kick off the encoding
            try
            {
                using (var stream = await tempFile.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item))
                    {
                        if (mediaCapture != null)
                        {
                            await mediaCapture.StartRecordToStorageFileAsync(MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High), micFile);
                        }
                        var encodesuccess = await _encoder.EncodeAsync(
                            stream,
                            width, height, bitrate,
                            frameRate, loopbackAudioCapture);

                        if (encodesuccess == false)
                        {
                            ContentDialog errorDialog = new ContentDialog
                            {
                                Title           = "Recording failed",
                                Content         = "Windows cannot encode your video",
                                CloseButtonText = "OK"
                            };
                            await errorDialog.ShowAsync();
                        }
                    }
                MainTextBlock.Foreground = originalBrush;

                Ellipse.Visibility = Visibility.Collapsed;
                visual.StopAnimation("Opacity");
            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex);
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex);

                var message = GetMessageForHResult(ex.HResult);
                if (message == null)
                {
                    message = $"Whoops, something went wrong!\n0x{ex.HResult:X8} - {ex.Message}";
                }
                ContentDialog errorDialog = new ContentDialog
                {
                    Title           = "Recording failed",
                    Content         = message,
                    CloseButtonText = "OK"
                };
                await errorDialog.ShowAsync();

                button.IsChecked = false;
                visual.StopAnimation("Opacity");

                Ellipse.Visibility = Visibility.Collapsed;


                MainTextBlock.Foreground = originalBrush;
                RecordIcon.Visibility    = Visibility.Visible;
                StopIcon.Visibility      = Visibility.Collapsed;
                toolTip.Content          = Strings.Resources.RecordingStart;
                ToolTipService.SetToolTip(MainButton, toolTip);
                AutomationProperties.SetName(MainButton, Strings.Resources.RecordingStart);
                await _tempFile.DeleteAsync();

                return;
            }


            // At this point the encoding has finished,
            // tell the user we're now saving

            if (AudioToggleSwitch.IsOn)
            {
                CompleteRecording(BufferList.ToArray(), width, height, bitrate, frameRate);
            }
            else if (ExtAudioToggleSwitch.IsOn)
            {
                var clip = await MediaClip.CreateFromFileAsync(_tempFile);

                var composition = new MediaComposition();
                composition.Clips.Add(clip);

                StorageFile internalAudioFile = micFile;
                mediaCapture.Dispose();
                mediaCapture = null;

                var backgroundTrack = await BackgroundAudioTrack.CreateFromFileAsync(internalAudioFile);

                composition.BackgroundAudioTracks.Add(backgroundTrack);

                var videoFile = _tempFile;

                var newFile = await GetTempFileAsync();

                MainTextBlock.Text             = Strings.Resources.Saving;
                MergingProgressRing.Visibility = Visibility.Visible;
                MainButton.Visibility          = Visibility.Collapsed;

                var merge = composition.RenderToFileAsync(newFile, MediaTrimmingPreference.Fast);
                merge.Progress = new AsyncOperationProgressHandler <TranscodeFailureReason, double>(async(info, progress) =>
                {
                    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() =>
                    {
                        MergingProgressRing.Value = progress;
                    }));
                });
                merge.Completed = new AsyncOperationWithProgressCompletedHandler <TranscodeFailureReason, double>(async(info, status) =>
                {
                    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(async() =>

                    {
                        MergingProgressRing.Value      = 0;
                        MergingProgressRing.Visibility = Visibility.Collapsed;
                        _tempFile = newFile;

                        MainButton.IsChecked = false;
                        MainTextBlock.Text   = "";
                        visual.StopAnimation("Opacity");
                        Ellipse.Visibility    = Visibility.Collapsed;
                        RecordIcon.Visibility = Visibility.Visible;
                        StopIcon.Visibility   = Visibility.Collapsed;
                        ToolTip newtoolTip    = new ToolTip();
                        toolTip.Content       = Strings.Resources.RecordingStart;
                        ToolTipService.SetToolTip(MainButton, toolTip);
                        AutomationProperties.SetName(MainButton, Strings.Resources.RecordingStart);
                        this.Frame.Navigate(typeof(VideoPreviewPage), _tempFile);
                        CacheCurrentSettings();

                        var videofolder = await KnownFolders.VideosLibrary.TryGetItemAsync("Fluent Screen Recorder");

                        MainButton.Visibility = Visibility.Visible;
                        await videoFile.DeleteAsync();
                        await internalAudioFile.DeleteAsync();
                    }));
                });
                lockAdaptiveUI = false;
            }
            else
            {
                MainButton.IsChecked = false;
                MainTextBlock.Text   = "";
                visual.StopAnimation("Opacity");
                Ellipse.Visibility    = Visibility.Collapsed;
                RecordIcon.Visibility = Visibility.Visible;
                StopIcon.Visibility   = Visibility.Collapsed;
                ToolTip newtoolTip = new ToolTip();
                toolTip.Content = Strings.Resources.RecordingStart;
                ToolTipService.SetToolTip(MainButton, Strings.Resources.RecordingStart);
                AutomationProperties.SetName(MainButton, "Start recording");
                this.Frame.Navigate(typeof(VideoPreviewPage), _tempFile);
                CacheCurrentSettings();
                lockAdaptiveUI = false;
            }
        }
Пример #26
0
        private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            var button = (ToggleButton)sender;

            // get storage folder
            if (storageFolder == null)
            {
                var msg = new MessageDialog("Please choose a folder first...");
                await msg.ShowAsync();

                button.IsChecked = false;
                return;
            }

            // check storage folder permissions
            try
            {
                var files = await storageFolder.GetFilesAsync();
            }
            catch
            {
                var dialog = new MessageDialog(
                    "The selected storage directory does not exist anymore or is not accessable. Please select a new directory.",
                    "Directory not found or not enough permissions");

                await dialog.ShowAsync();

                button.IsChecked = false;
                return;
            }

            var requestSuspensionExtension = new ExtendedExecutionForegroundSession();

            requestSuspensionExtension.Reason = ExtendedExecutionForegroundReason.Unspecified;
            var requestExtensionResult = await requestSuspensionExtension.RequestExtensionAsync();

            // get storage files
            var time = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss_");

            var screenFile = await storageFolder.CreateFileAsync(time + "slides.mp4");

            var webcamFile = await storageFolder.CreateFileAsync(time + "talkinghead.mp4");

            var jsonFile = await storageFolder.CreateFileAsync(time + "meta.json");

            // get encoder properties
            var frameRate     = uint.Parse(((string)FrameRateComboBox.SelectedItem).Replace("fps", ""));
            var quality       = (VideoEncodingQuality)Enum.Parse(typeof(VideoEncodingQuality), (string)QualityComboBox.SelectedItem, false);
            var useSourceSize = UseCaptureItemSizeCheckBox.IsChecked.Value;

            var  temp    = MediaEncodingProfile.CreateMp4(quality);
            uint bitrate = 2500000;
            var  width   = temp.Video.Width;
            var  height  = temp.Video.Height;

            // get capture item
            var picker = new GraphicsCapturePicker();

            captureItem = await picker.PickSingleItemAsync();

            if (captureItem == null)
            {
                button.IsChecked = false;
                return;
            }

            // use the capture item's size for the encoding if desired
            if (useSourceSize)
            {
                width  = (uint)captureItem.Size.Width;
                height = (uint)captureItem.Size.Height;
            }

            // we have a screen resolution of more than 4K?
            if (width > 1920)
            {
                var v = width / 1920;
                width   = 1920;
                height /= v;
            }

            // even if we're using the capture item's real size,
            // we still want to make sure the numbers are even.
            width  = EnsureEven(width);
            height = EnsureEven(height);

            // tell the user we've started recording
            var originalBrush = MainTextBlock.Foreground;

            MainTextBlock.Foreground        = new SolidColorBrush(Colors.Red);
            MainProgressBar.IsIndeterminate = true;

            button.IsEnabled = false;

            MainTextBlock.Text = "3";
            await Task.Delay(1000);

            MainTextBlock.Text = "2";
            await Task.Delay(1000);

            MainTextBlock.Text = "1";
            await Task.Delay(1000);

            button.IsEnabled = true;

            MainTextBlock.Text = "● rec";

            _timerCount = 0;
            _timer.Start();

            try
            {
                // start webcam recording
                MediaEncodingProfile webcamEncodingProfile = null;

                if (AdaptBitrateCheckBox.IsChecked.Value)
                {
                    var selectedItem       = WebcamComboBox.SelectedItem as ComboBoxItem;
                    var encodingProperties = (selectedItem.Tag as StreamPropertiesHelper);

                    if (encodingProperties.Height > 720)
                    {
                        webcamEncodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);
                        webcamEncodingProfile.Video.Bitrate = 8000000;
                    }
                    else if (encodingProperties.Height > 480)
                    {
                        webcamEncodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);
                        webcamEncodingProfile.Video.Bitrate = 5000000;
                    }
                    else
                    {
                        webcamEncodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
                    }
                }
                else
                {
                    webcamEncodingProfile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
                }

                mediaRecording = await mediaCapture.PrepareLowLagRecordToStorageFileAsync(webcamEncodingProfile, webcamFile);

                // kick off the screen encoding parallel
                using (var stream = await screenFile.OpenAsync(FileAccessMode.ReadWrite))
                    using (screenCapture = new Encoder(screenDevice, captureItem))
                    {
                        // webcam recording
                        if (mediaCapture != null)
                        {
                            await mediaRecording.StartAsync();
                        }

                        // screen recording
                        await screenCapture.EncodeAsync(
                            stream,
                            width, height, bitrate,
                            frameRate);
                    }

                MainTextBlock.Foreground = originalBrush;

                // user has finished recording, so stop webcam recording
                await mediaRecording.StopAsync();

                await mediaRecording.FinishAsync();

                _timer.Stop();
            }
            catch (Exception ex)
            {
                _timer.Stop();

                var dialog = new MessageDialog(
                    $"Uh-oh! Something went wrong!\n0x{ex.HResult:X8} - {ex.Message}",
                    "Recording failed");

                await dialog.ShowAsync();

                button.IsChecked                = false;
                MainTextBlock.Text              = "failure";
                MainTextBlock.Foreground        = originalBrush;
                MainProgressBar.IsIndeterminate = false;

                captureItem = null;
                if (mediaRecording != null)
                {
                    await mediaRecording.StopAsync();

                    await mediaRecording.FinishAsync();
                }

                return;
            }

            // at this point the encoding has finished
            MainTextBlock.Text = "saving...";

            // save slide markers
            var recording = new Recording()
            {
                Slides = screenCapture.GetTimestamps()
            };

            var settings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };

            var json = JsonConvert.SerializeObject(recording, Formatting.Indented, settings);
            await FileIO.WriteTextAsync(jsonFile, json);

            // add metadata
            var recordingMetadataDialog       = new RecordingMetadataDialog();
            var recordingMetadataDialogResult = await recordingMetadataDialog.ShowAsync();

            if (recordingMetadataDialogResult == ContentDialogResult.Primary)
            {
                recording.Description = recordingMetadataDialog.LectureTitle;

                if (recordingMetadataDialog.LectureDate.HasValue)
                {
                    recording.LectureDate = recordingMetadataDialog.LectureDate.Value.DateTime;
                }
            }
            else
            {
                recording.Description = null;
                recording.LectureDate = DateTime.Now;
            }

            json = JsonConvert.SerializeObject(recording, Formatting.Indented, settings);
            await FileIO.WriteTextAsync(jsonFile, json);

            // tell the user we're done
            button.IsChecked   = false;
            MainTextBlock.Text = "done";
            MainProgressBar.IsIndeterminate = false;

            requestSuspensionExtension.Dispose();
        }
Пример #27
0
        private async void ScreenshotButton_Click(object sender, RoutedEventArgs e)
        {
            var filePicker = new FileSavePicker();

            filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            filePicker.SuggestedFileName      = "screenshot";
            filePicker.DefaultFileExtension   = ".png";
            filePicker.FileTypeChoices.Add("PNG Image", new string[] { ".png" });
            var file = await filePicker.PickSaveFileAsync();

            if (file != null)
            {
                var capturePicker = new GraphicsCapturePicker();
                var item          = await capturePicker.PickSingleItemAsync();

                if (item != null)
                {
                    var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
                        _device,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        1,
                        item.Size);
                    var session = framePool.CreateCaptureSession(item);

                    var completionSource = new TaskCompletionSource <Direct3D11Texture2D>();
                    framePool.FrameArrived += (s, a) =>
                    {
                        using (var frame = s.TryGetNextFrame())
                        {
                            var frameTexture = Direct3D11Texture2D.CreateFromDirect3DSurface(frame.Surface);
                            var description  = frameTexture.Description2D;
                            description.Usage          = Direct3DUsage.Staging;
                            description.BindFlags      = 0;
                            description.CpuAccessFlags = Direct3D11CpuAccessFlag.AccessRead;
                            description.MiscFlags      = 0;
                            var copyTexture = _device.CreateTexture2D(description);

                            _deviceContext.CopyResource(copyTexture, frameTexture);

                            session.Dispose();
                            framePool.Dispose();

                            completionSource.SetResult(copyTexture);
                        }
                    };

                    session.StartCapture();
                    var texture = await completionSource.Task;
                    var bits    = texture.GetBytes();

                    using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                    {
                        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);

                        encoder.SetPixelData(
                            BitmapPixelFormat.Bgra8,
                            BitmapAlphaMode.Premultiplied,
                            (uint)item.Size.Width,
                            (uint)item.Size.Height,
                            1.0,
                            1.0,
                            bits);
                        await encoder.FlushAsync();
                    }

                    await Launcher.LaunchFileAsync(file);
                }
            }
        }
Пример #28
0
        private async void MainToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            // Select what we want to capture
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item != null)
            {
                // Get a temporary file to save our gif to
                var file = await GetTempFileAsync();

                using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    // Get the various d3d objects we'll need
                    var d3dDevice = Direct3D11Helpers.CreateSharpDXDevice(_device);

                    // Create our encoder
                    var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, stream);

                    // Write the application block
                    // http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
                    var containerProperties = encoder.BitmapContainerProperties;
                    await containerProperties.SetPropertiesAsync(new[]
                    {
                        new KeyValuePair <string, BitmapTypedValue>("/appext/application", new BitmapTypedValue(PropertyValue.CreateUInt8Array(Encoding.ASCII.GetBytes("NETSCAPE2.0")), PropertyType.UInt8Array)),
                        // The first value is the size of the block, which is the fixed value 3.
                        // The second value is the looping extension, which is the fixed value 1.
                        // The third and fourth values comprise an unsigned 2-byte integer (little endian).
                        //     The value of 0 means to loop infinitely.
                        // The final value is the block terminator, which is the fixed value 0.
                        new KeyValuePair <string, BitmapTypedValue>("/appext/data", new BitmapTypedValue(PropertyValue.CreateUInt8Array(new byte[] { 3, 1, 0, 0, 0 }), PropertyType.UInt8Array)),
                    });

                    // Setup Windows.Graphics.Capture
                    var itemSize  = item.Size;
                    var framePool = Direct3D11CaptureFramePool.CreateFreeThreaded(
                        _device,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        1,
                        itemSize);
                    var session = framePool.CreateCaptureSession(item);

                    // We need a blank texture (background) and a texture that will hold the frame we'll be encoding
                    var description = new SharpDX.Direct3D11.Texture2DDescription
                    {
                        Width             = itemSize.Width,
                        Height            = itemSize.Height,
                        MipLevels         = 1,
                        ArraySize         = 1,
                        Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                        SampleDescription = new SharpDX.DXGI.SampleDescription()
                        {
                            Count   = 1,
                            Quality = 0
                        },
                        Usage          = SharpDX.Direct3D11.ResourceUsage.Default,
                        BindFlags      = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget,
                        CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
                        OptionFlags    = SharpDX.Direct3D11.ResourceOptionFlags.None
                    };
                    var gifTexture       = new SharpDX.Direct3D11.Texture2D(d3dDevice, description);
                    var renderTargetView = new SharpDX.Direct3D11.RenderTargetView(d3dDevice, gifTexture);

                    // Encode frames as they arrive. Because we created our frame pool using
                    // Direct3D11CaptureFramePool::CreateFreeThreaded, this lambda will fire on a different thread
                    // than our current one. If you'd like the callback to fire on your thread, create the frame pool
                    // using Direct3D11CaptureFramePool::Create and make sure your thread has a DispatcherQueue and you
                    // are pumping messages.
                    TimeSpan lastTimeStamp = TimeSpan.MinValue;
                    var      frameCount    = 0;
                    framePool.FrameArrived += async(s, a) =>
                    {
                        using (var frame = s.TryGetNextFrame())
                        {
                            var contentSize = frame.ContentSize;
                            var timeStamp   = frame.SystemRelativeTime;
                            using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(frame.Surface))
                            {
                                var width  = Math.Clamp(contentSize.Width, 0, itemSize.Width);
                                var height = Math.Clamp(contentSize.Height, 0, itemSize.Height);

                                var region = new SharpDX.Direct3D11.ResourceRegion(0, 0, 0, width, height, 1);

                                d3dDevice.ImmediateContext.ClearRenderTargetView(renderTargetView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 1));
                                d3dDevice.ImmediateContext.CopySubresourceRegion(sourceTexture, 0, region, gifTexture, 0);
                            }

                            if (lastTimeStamp == TimeSpan.MinValue)
                            {
                                lastTimeStamp = timeStamp;
                            }
                            var timeStampDelta = timeStamp - lastTimeStamp;
                            lastTimeStamp = timeStamp;
                            var milliseconds = timeStampDelta.TotalMilliseconds;
                            // Use 10ms units
                            var frameDelay = milliseconds / 10;

                            if (frameCount > 0)
                            {
                                await encoder.GoToNextFrameAsync();
                            }

                            // Write our frame delay
                            await encoder.BitmapProperties.SetPropertiesAsync(new[]
                            {
                                new KeyValuePair <string, BitmapTypedValue>("/grctlext/Delay", new BitmapTypedValue(PropertyValue.CreateUInt16((ushort)frameDelay), PropertyType.UInt16)),
                            });

                            // Write the frame to our image
                            var gifSurface = Direct3D11Helpers.CreateDirect3DSurfaceFromSharpDXTexture(gifTexture);
                            var copy       = await SoftwareBitmap.CreateCopyFromSurfaceAsync(gifSurface);

                            encoder.SetSoftwareBitmap(copy);
                            frameCount++;
                        }
                    };

                    session.StartCapture();

                    await _semaphore.WaitAsync();

                    session.Dispose();
                    framePool.Dispose();
                    await Task.Delay(1000);

                    await encoder.FlushAsync();

                    var newFile = await PickGifAsync();

                    if (newFile == null)
                    {
                        await file.DeleteAsync();

                        return;
                    }
                    await file.MoveAndReplaceAsync(newFile);

                    await Launcher.LaunchFileAsync(newFile);
                }
            }
        }
Пример #29
0
        private async void ToggleButton_Checked(object sender, RoutedEventArgs e)
        {
            var button = (ToggleButton)sender;

            // Get our encoder properties
            var frameRateItem  = (FrameRateItem)FrameRateComboBox.SelectedItem;
            var resolutionItem = (ResolutionItem)ResolutionComboBox.SelectedItem;
            var bitrateItem    = (BitrateItem)BitrateComboBox.SelectedItem;

            if (UseCaptureItemToggleSwitch.IsOn)
            {
                resolutionItem.IsZero();
            }

            var width     = resolutionItem.Resolution.Width;
            var height    = resolutionItem.Resolution.Height;
            var bitrate   = bitrateItem.Bitrate;
            var frameRate = frameRateItem.FrameRate;

            if (UseCaptureItemToggleSwitch.IsOn)
            {
                resolutionItem.IsZero();
            }

            // Get our capture item
            var picker = new GraphicsCapturePicker();
            var item   = await picker.PickSingleItemAsync();

            if (item == null)
            {
                button.IsChecked = false;
                return;
            }

            // Use the capture item's size for the encoding if desired
            if (UseCaptureItemToggleSwitch.IsOn)
            {
                width  = (uint)item.Size.Width;
                height = (uint)item.Size.Height;

                // Even if we're using the capture item's real size,
                // we still want to make sure the numbers are even.
                // Some encoders get mad if you give them odd numbers.
                width  = EnsureEven(width);
                height = EnsureEven(height);
            }

            // Put videos in the temp folder
            var tempFile = await GetTempFileAsync();

            _tempFile = tempFile;

            // Tell the user we've started recording

            var visual    = ElementCompositionPreview.GetElementVisual(Ellipse);
            var animation = visual.Compositor.CreateScalarKeyFrameAnimation();

            animation.InsertKeyFrame(0, 1);
            animation.InsertKeyFrame(1, 0);
            animation.Duration          = TimeSpan.FromMilliseconds(1500);
            animation.IterationBehavior = AnimationIterationBehavior.Forever;
            visual.StartAnimation("Opacity", animation);

            RecordIcon.Visibility = Visibility.Collapsed;
            StopIcon.Visibility   = Visibility.Visible;
            Ellipse.Visibility    = Visibility.Visible;
            ToolTip toolTip = new ToolTip();

            toolTip.Content = "Stop recording";
            ToolTipService.SetToolTip(MainButton, toolTip);
            AutomationProperties.SetName(MainButton, "Stop recording");
            MainTextBlock.Text = "recording...";
            var originalBrush = MainTextBlock.Foreground;

            MainTextBlock.Foreground = new SolidColorBrush(Colors.Red);

            // Kick off the encoding
            try
            {
                using (var stream = await tempFile.OpenAsync(FileAccessMode.ReadWrite))
                    using (_encoder = new Encoder(_device, item))
                    {
                        var encodesuccess = await _encoder.EncodeAsync(
                            stream,
                            width, height, bitrate,
                            frameRate);

                        if (encodesuccess == false)
                        {
                            ContentDialog errorDialog = new ContentDialog
                            {
                                Title           = "Recording failed",
                                Content         = "Windows cannot encode your video",
                                CloseButtonText = "OK"
                            };
                            await errorDialog.ShowAsync();
                        }
                    }
                MainTextBlock.Foreground = originalBrush;
            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex);
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex);

                var message = GetMessageForHResult(ex.HResult);
                if (message == null)
                {
                    message = $"Whoops, something went wrong!\n0x{ex.HResult:X8} - {ex.Message}";
                }
                ContentDialog errorDialog = new ContentDialog
                {
                    Title           = "Recording failed",
                    Content         = message,
                    CloseButtonText = "OK"
                };
                await errorDialog.ShowAsync();

                button.IsChecked = false;
                visual.StopAnimation("Opacity");

                Ellipse.Visibility       = Visibility.Collapsed;
                MainTextBlock.Text       = "failure";
                MainTextBlock.Foreground = originalBrush;
                RecordIcon.Visibility    = Visibility.Visible;
                StopIcon.Visibility      = Visibility.Collapsed;
                toolTip.Content          = "Start recording";
                ToolTipService.SetToolTip(MainButton, toolTip);
                AutomationProperties.SetName(MainButton, "Start recording");
                await _tempFile.DeleteAsync();

                return;
            }

            // At this point the encoding has finished,
            // tell the user we're now saving

            MainButton.IsChecked = false;
            MainTextBlock.Text   = "";
            visual.StopAnimation("Opacity");
            Ellipse.Visibility    = Visibility.Collapsed;
            RecordIcon.Visibility = Visibility.Visible;
            StopIcon.Visibility   = Visibility.Collapsed;
            ToolTip newtoolTip = new ToolTip();

            toolTip.Content = "Start recording";
            ToolTipService.SetToolTip(MainButton, toolTip);
            AutomationProperties.SetName(MainButton, "Start recording");

            if (PreviewToggleSwitch.IsOn)
            {
                CoreApplicationView newView = CoreApplication.CreateNewView();
                int newViewId = 0;
                await newView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    var preview = new VideoPreviewPage(_tempFile);
                    ApplicationViewTitleBar formattableTitleBar = ApplicationView.GetForCurrentView().TitleBar;
                    formattableTitleBar.ButtonBackgroundColor   = Colors.Transparent;
                    CoreApplicationViewTitleBar coreTitleBar    = CoreApplication.GetCurrentView().TitleBar;
                    coreTitleBar.ExtendViewIntoTitleBar         = true;
                    Window.Current.Content = preview;
                    Window.Current.Activate();
                    newViewId = ApplicationView.GetForCurrentView().Id;
                });

                bool viewShown = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(newViewId);
            }
            else
            {
                ContentDialog dialog = new SaveDialog(_tempFile);
                await dialog.ShowAsync();
            }
        }