Skip to main content

windows_capture/
lib.rs

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