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; } }
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(); }
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; } }
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); }
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()); }