Skip to content

Commit

Permalink
Native Encoder And Better Documentation 🔥⭐
Browse files Browse the repository at this point in the history
	modified:   Cargo.lock
	modified:   Cargo.toml
	modified:   README.md
	modified:   examples/basic.rs
	modified:   src/capture.rs
	modified:   src/d3d11.rs
	new file:   src/encoder.rs
	modified:   src/frame.rs
	modified:   src/graphics_capture_api.rs
	modified:   src/lib.rs
	modified:   src/monitor.rs
	modified:   src/settings.rs
	modified:   src/window.rs
	modified:   windows-capture-python/Cargo.toml
	modified:   windows-capture-python/README.md
	modified:   windows-capture-python/pyproject.toml
	modified:   windows-capture-python/src/lib.rs
	modified:   windows-capture-python/windows_capture/__init__.py
  • Loading branch information
NiiightmareXD committed Mar 2, 2024
1 parent 27bb086 commit b9d5bf5
Show file tree
Hide file tree
Showing 18 changed files with 1,433 additions and 506 deletions.
72 changes: 36 additions & 36 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 12 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "windows-capture"
version = "1.0.61"
version = "1.0.62"
authors = ["NiiightmareXD"]
edition = "2021"
description = "Fastest Windows Screen Capture Library For Rust 🔥"
Expand All @@ -19,10 +19,8 @@ categories = [
resolver = "2"

[dependencies]
parking_lot = "0.12.1"
rayon = "1.8.1"
thiserror = "1.0.57"
windows = { version = "0.53.0", features = [
# Windows API
windows = { version = "0.54.0", features = [
"Win32_System_WinRT_Graphics_Capture",
"Win32_Graphics_Direct3D11",
"Win32_Foundation",
Expand All @@ -46,6 +44,15 @@ windows = { version = "0.53.0", features = [
"Media_Transcoding",
] }

# Mutex optimization
parking_lot = "0.12.1"

# Multithreading
rayon = "1.8.1"

# Error handling
thiserror = "1.0.57"

[package.metadata.docs.rs]
default-target = "x86_64-pc-windows-msvc"
targets = ["x86_64-pc-windows-msvc"]
Expand Down
96 changes: 67 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Add this library to your `Cargo.toml`:

```toml
[dependencies]
windows-capture = "1.0.61"
windows-capture = "1.0.62"
```
or run this command

Expand All @@ -37,51 +37,88 @@ cargo add windows-capture
## Usage

```rust
use std::{
io::{self, Write},
time::Instant,
};

use windows_capture::{
capture::WindowsCaptureHandler,
frame::{Frame, ImageFormat},
capture::GraphicsCaptureApiHandler,
encoder::{VideoEncoder, VideoEncoderQuality, VideoEncoderType},
frame::Frame,
graphics_capture_api::InternalCaptureControl,
settings::{ColorFormat, Settings},
window::Window,
monitor::Monitor,
settings::{ColorFormat, CursorCaptuerSettings, DrawBorderSettings, Settings},
};

// Struct To Implement The Trait For
struct Capture;
// This struct will be used to handle the 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 WindowsCaptureHandler for Capture {
// Any Value To Get From The Settings
impl GraphicsCaptureApiHandler for Capture {
// The type of flags used to get the values from the settings.
type Flags = String;

// To Redirect To `CaptureControl` Or Start Method
// The type of error that can occur during capture, the error will be returned from `CaptureControl` and `start` functions.
type Error = Box<dyn std::error::Error + Send + Sync>;

// Function That Will Be Called To Create The Struct The Flags Can Be Passed
// From `WindowsCaptureSettings`
// Function that will be called to create the struct. The flags can be passed from settings.
fn new(message: Self::Flags) -> Result<Self, Self::Error> {
println!("Got The Flag: {message}");

Ok(Self {})
let encoder = VideoEncoder::new(
VideoEncoderType::Mp4,
VideoEncoderQuality::HD1080p,
1920,
1080,
"video.mp4",
)?;

Ok(Self {
encoder: Some(encoder),
start: Instant::now(),
})
}

// Called Every Time A New Frame Is Available
// Called every time a new frame is available.
fn on_frame_arrived(
&mut self,
frame: &mut Frame,
capture_control: InternalCaptureControl,
) -> Result<(), Self::Error> {
println!("New Frame Arrived");
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)?;

// Note: The frame has other uses too for example you can save a single for 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()?;

// Save The Frame As An Image To The Specified Path
frame.save_as_image("image.png", ImageFormat::Png)?;
capture_control.stop();

// Gracefully Stop The Capture Thread
capture_control.stop();
// Because there wasn't any new lines in previous prints
println!();
}

Ok(())
}

// Called When The Capture Item Closes Usually When The Window Closes, Capture
// Session Will End After This Function Ends
// Optional handler called when the capture item (usually a window) closes.
fn on_closed(&mut self) -> Result<(), Self::Error> {
println!("Capture Session Closed");

Expand All @@ -91,23 +128,24 @@ impl WindowsCaptureHandler for Capture {

fn main() {
// Gets The Foreground Window, Checkout The Docs For Other Capture Items
let foreground_window = Window::foreground().expect("No Active Window Found");
let primary_monitor = Monitor::primary().expect("There is no primary monitor");

let settings = Settings::new(
// Item To Captue
foreground_window,
primary_monitor,
// Capture Cursor
Some(true),
CursorCaptuerSettings::Default,
// Draw Borders (None Means Default Api Configuration)
None,
// Kind Of Pixel Format For Frame To Have
DrawBorderSettings::Default,
// The desired color format for the captured frame.
ColorFormat::Rgba8,
// Any Value To Pass To The New Function
"It Works".to_string(),
// Additional flags for the capture settings that will be passed to user defined `new` function.
"Yea This Works".to_string(),
)
.unwrap();

// Every Error From `new`, `on_frame_arrived` and `on_closed` Will End Up Here
// Starts the capture and takes control of the current thread.
// The errors from handler trait will end up here
Capture::start(settings).expect("Screen Capture Failed");
}
```
Expand Down
Loading

0 comments on commit b9d5bf5

Please sign in to comment.