private async void InternalAudioCheck()
        {
            try
            {
                loopbackAudioCapture = new LoopbackAudioCapture(MediaDevice.GetDefaultAudioRenderId(AudioDeviceRole.Default));
                await loopbackAudioCapture.Start();

                await loopbackAudioCapture.Stop();

                loopbackAudioCapture = null;
            }
            catch (Exception)
            {
                AudioToggleSwitch.IsOn = false;
            }
        }
Пример #2
0
        private async void InitializeCapture(SizeInt32 size, LoopbackAudioCapture loopbackAudioCapture)
        {
            _item.Closed += OnClosed;
            _framePool    = Direct3D11CaptureFramePool.CreateFreeThreaded(
                _device,
                DirectXPixelFormat.B8G8R8A8UIntNormalized,
                1,
                size);
            _framePool.FrameArrived += OnFrameArrived;
            _session = _framePool.CreateCaptureSession(_item);

            if (loopbackAudioCapture != null)
            {
                await loopbackAudioCapture.Start();
            }

            _session.StartCapture();
        }
Пример #3
0
        public CaptureFrameWait(
            IDirect3DDevice device,
            GraphicsCaptureItem item,
            SizeInt32 size,
            LoopbackAudioCapture loopbackAudioCapture)
        {
            _device      = device;
            _d3dDevice   = Direct3D11Helpers.CreateSharpDXDevice(device);
            _multithread = _d3dDevice.QueryInterface <SharpDX.Direct3D11.Multithread>();
            _multithread.SetMultithreadProtected(true);
            _item        = item;
            _frameEvent  = new ManualResetEvent(false);
            _closedEvent = new ManualResetEvent(false);
            _events      = new[] { _closedEvent, _frameEvent };

            InitializeBlankTexture(size);
            InitializeCapture(size, loopbackAudioCapture);
        }
        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;
            }
        }
Пример #5
0
        private async Task <bool> EncodeInternalAsync(IRandomAccessStream stream, uint width, uint height, uint bitrateInBps, uint frameRate, LoopbackAudioCapture loopbackAudioCapture)
        {
            if (!_isRecording)
            {
                _isRecording = true;

                _frameGenerator = new CaptureFrameWait(
                    _device,
                    _captureItem,
                    _captureItem.Size,
                    loopbackAudioCapture);

                using (_frameGenerator)
                {
                    var encodingProfile = new MediaEncodingProfile();
                    encodingProfile.Container.Subtype                  = "MPEG4";
                    encodingProfile.Video.Subtype                      = "H264";
                    encodingProfile.Video.Width                        = width;
                    encodingProfile.Video.Height                       = height;
                    encodingProfile.Video.Bitrate                      = bitrateInBps;
                    encodingProfile.Video.FrameRate.Numerator          = frameRate;
                    encodingProfile.Video.FrameRate.Denominator        = 1;
                    encodingProfile.Video.PixelAspectRatio.Numerator   = 1;
                    encodingProfile.Video.PixelAspectRatio.Denominator = 1;

                    var transcode = await _transcoder.PrepareMediaStreamSourceTranscodeAsync(_mediaStreamSource, stream, encodingProfile);

                    if (transcode.CanTranscode)
                    {
                        await transcode.TranscodeAsync();

                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #6
0
 public IAsyncOperation <bool> EncodeAsync(IRandomAccessStream stream, uint width, uint height, uint bitrateInBps, uint frameRate, LoopbackAudioCapture loopbackAudioCapture)
 {
     return(EncodeInternalAsync(stream, width, height, bitrateInBps, frameRate, loopbackAudioCapture).AsAsyncOperation());
 }