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; }
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(); } }
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); }
public async Task StartAsync() { var item = await picker.PickSingleItemAsync(); if (item != null) { var capture = new BasicCapture(device, item); this.currentCapture = capture; capture.StartCapture(); } }
private async Task StartPickerCaptureAsync() { var picker = new GraphicsCapturePicker(); picker.SetWindow(hwnd); GraphicsCaptureItem item = await picker.PickSingleItemAsync(); if (item != null) { sample.StartCaptureFromItem(item); } }
public async Task StartCaptureAsync() { // 让用户选择哪个应用 var picker = new GraphicsCapturePicker(); GraphicsCaptureItem item = await picker.PickSingleItemAsync(); // 如果用户有选择一个应用那么这个属性不为空 if (item != null) { StartCaptureInternal(item); } }
public async Task StartCaptureAsync() { var picker = new GraphicsCapturePicker(); GraphicsCaptureItem item = await picker.PickSingleItemAsync(); if (item != null) { _captureFolder = await _setupCpatureFolder(); _startCaptureInternal(item); } }
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); }
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); }); }
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); } }
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); } }
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); } }
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; } } }
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); } }
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); } }
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; }
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; }
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(); }
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); } }
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; } }
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; } }
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(); }
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); } } }
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); } } }
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(); } }