1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//! # Windows Capture Rust Library
//!
//! **Windows Capture** is a highly efficient Rust and Python library that
//! enables you to effortlessly capture the screen using the Graphics Capture
//! API. This library allows you to easily capture the screen of your
//! Windows-based computer and use it for various purposes, such as creating
//! instructional videos, taking screenshots, or recording your gameplay. With
//! its intuitive interface and robust functionality, Windows Capture is an
//! excellent choice for anyone looking for a reliable and easy-to-use screen
//! capturing solution.
//!
//! ## Features
//!
//! - Updates frames only when required
//! - High performance
//! - Easy to use
//! - Uses the latest Windows Graphics Capture API
//! - Supports the DXGI Desktop Duplication API
//! - Enhanced, hardware-accelerated video encoder with stable audio timing
//!
//! ## Installation
//!
//! Add this library to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! windows-capture = "2.0.0"
//! ```
//! Or run this command:
//!
//! ```text
//! cargo add windows-capture
//! ```
//!
//! ## Usage
//!
//! ```no_run
//! use std::io::{self, Write};
//! use std::time::Instant;
//!
//! use windows_capture::capture::{Context, GraphicsCaptureApiHandler};
//! use windows_capture::encoder::{
//! AudioSettingsBuilder, ContainerSettingsBuilder, VideoEncoder, VideoSettingsBuilder,
//! };
//! use windows_capture::frame::Frame;
//! use windows_capture::graphics_capture_api::InternalCaptureControl;
//! use windows_capture::graphics_capture_picker::GraphicsCapturePicker;
//! use windows_capture::settings::{
//! ColorFormat, CursorCaptureSettings, DirtyRegionSettings, DrawBorderSettings,
//! MinimumUpdateIntervalSettings, SecondaryWindowSettings, Settings,
//! };
//!
//! // Handles capture events.
//! struct Capture {
//! // The video encoder that will be used to encode the frames.
//! encoder: Option<VideoEncoder>,
//! // To measure the time the capture has been running
//! start: Instant,
//! }
//!
//! impl GraphicsCaptureApiHandler for Capture {
//! // The type of flags used to get the values from the settings, here they are the width and height.
//! type Flags = (i32, i32);
//!
//! // The type of error that can be returned from `CaptureControl` and `start`
//! // functions.
//! type Error = Box<dyn std::error::Error + Send + Sync>;
//!
//! // Function that will be called to create a new instance. The flags can be
//! // passed from settings.
//! fn new(ctx: Context<Self::Flags>) -> Result<Self, Self::Error> {
//! // If we didn't want to get the size from the settings, we could use frame.width() and frame.height()
//! // in the on_frame_arrived function, but we would need to create the encoder there.
//! let encoder = VideoEncoder::new(
//! VideoSettingsBuilder::new(ctx.flags.0 as u32, ctx.flags.1 as u32),
//! AudioSettingsBuilder::default().disabled(true),
//! ContainerSettingsBuilder::default(),
//! "video.mp4",
//! )?;
//!
//! Ok(Self { encoder: Some(encoder), start: Instant::now() })
//! }
//!
//! // Called every time a new frame is available.
//! fn on_frame_arrived(
//! &mut self,
//! frame: &mut Frame,
//! capture_control: InternalCaptureControl,
//! ) -> Result<(), Self::Error> {
//! print!("\rRecording for: {} seconds", self.start.elapsed().as_secs());
//! io::stdout().flush()?;
//!
//! // Send the frame to the video encoder
//! self.encoder.as_mut().unwrap().send_frame(frame)?;
//!
//! // The frame has other uses too, for example, you can save a single frame
//! // to a file, like this: frame.save_as_image("frame.png", ImageFormat::Png)?;
//! // Or get the raw data like this so you have full control: let data = frame.buffer()?;
//!
//! // Stop the capture after 6 seconds
//! if self.start.elapsed().as_secs() >= 6 {
//! // Finish the encoder and save the video.
//! self.encoder.take().unwrap().finish()?;
//!
//! capture_control.stop();
//!
//! // Because the previous prints did not include a newline.
//! println!();
//! }
//!
//! Ok(())
//! }
//!
//! // Optional handler called when the capture item (usually a window) is closed.
//! fn on_closed(&mut self) -> Result<(), Self::Error> {
//! println!("Capture session ended");
//!
//! Ok(())
//! }
//! }
//!
//! // Opens a dialog to pick a window or screen to capture; refer to the docs for other capture items.
//! let item = GraphicsCapturePicker::pick_item().expect("Failed to pick item");
//!
//! // If the user canceled the selection, exit.
//! let Some(item) = item else {
//! println!("No item selected");
//! return;
//! };
//!
//! // Get the size of the item to pass to the settings.
//! let size = item.size().expect("Failed to get item size");
//!
//! let settings = Settings::new(
//! // Item to capture
//! item,
//! // Capture cursor settings
//! CursorCaptureSettings::Default,
//! // Draw border settings
//! DrawBorderSettings::Default,
//! // Secondary window settings, if you want to include secondary windows in the capture
//! SecondaryWindowSettings::Default,
//! // Minimum update interval, if you want to change the frame rate limit (default is 60 FPS or 16.67 ms)
//! MinimumUpdateIntervalSettings::Default,
//! // Dirty region settings
//! DirtyRegionSettings::Default,
//! // The desired color format for the captured frame.
//! ColorFormat::Rgba8,
//! // Additional flags for the capture settings that will be passed to the user-defined `new` function.
//! size,
//! );
//!
//! // Starts the capture and takes control of the current thread.
//! // The errors from the handler trait will end up here.
//! Capture::start(settings).expect("Screen capture failed");
//! ```
/// Exported for the trait bounds
pub use GraphicsCaptureItem;
/// Contains safe wrapper for WinRT initialization.
pub
/// Contains the main capture functionality, including the
/// [`crate::capture::GraphicsCaptureApiHandler`] trait and related types.
/// Internal module for Direct3D 11 related functionality.
/// Contains types and functions related to the DXGI Desktop Duplication API.
/// Contains the encoder functionality for encoding captured frames, including
/// [`crate::encoder::VideoEncoder`].
/// Contains the [`crate::frame::Frame`] struct and related types for representing captured frames.
/// Contains the types and functions related to the Graphics Capture API.
/// Contains the functionality for displaying a picker to select a window or screen to capture:
/// [`crate::graphics_capture_picker::GraphicsCapturePicker`].
/// Contains functionality for working with monitors and screen information:
/// [`crate::monitor::Monitor`].
/// Contains the [`crate::settings::Settings`] struct and related types for configuring capture
/// settings.
/// Contains functionality for working with windows and capturing specific windows:
/// [`crate::window::Window`].