Giter Club home page Giter Club logo

windows-capture's Introduction

Windows Capture   Licence Build Status Latest Version

Windows Capture is a highly efficient Rust and Python library that enables you to capture the screen using the Graphics Capture API effortlessly. 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, easy-to-use screen-capturing solution.

Note this README.md is for Rust library Python library can be found here

Features

  • Only Updates The Frame When Required.
  • High Performance.
  • Easy To Use.
  • Latest Screen Capturing API.

Installation

Add this library to your Cargo.toml:

[dependencies]
windows-capture = "1.1.7"

or run this command

cargo add windows-capture

Usage

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

use windows_capture::{
    capture::GraphicsCaptureApiHandler,
    encoder::{VideoEncoder, VideoEncoderQuality, VideoEncoderType},
    frame::Frame,
    graphics_capture_api::InternalCaptureControl,
    monitor::Monitor,
    settings::{ColorFormat, CursorCaptureSettings, DrawBorderSettings, Settings},
};

// 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 GraphicsCaptureApiHandler for Capture {
    // The type of flags used to get the values from the settings.
    type Flags = String;

    // 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 settings.
    fn new(message: Self::Flags) -> Result<Self, Self::Error> {
        println!("Got The Flag: {message}");

        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.
    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)?;

        // 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()?;

            capture_control.stop();

            // Because there wasn't any new lines in previous prints
            println!();
        }

        Ok(())
    }

    // Optional handler called when the capture item (usually a window) closes.
    fn on_closed(&mut self) -> Result<(), Self::Error> {
        println!("Capture Session Closed");

        Ok(())
    }
}

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

    let settings = Settings::new(
        // Item To Captue
        primary_monitor,
        // Capture Cursor Settings
        CursorCaptureSettings::Default,
        // Draw Borders Settings
        DrawBorderSettings::Default,
        // The desired color format for the captured frame.
        ColorFormat::Rgba8,
        // Additional flags for the capture settings that will be passed to user defined `new` function.
        "Yea This Works".to_string(),
    )
    .unwrap();

    // 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");
}

Documentation

Detailed documentation for each API and type can be found here.

Contributing

Contributions are welcome! If you find a bug or want to add new features to the library, please open an issue or submit a pull request.

License

This project is licensed under the MIT License.

windows-capture's People

Contributors

dependabot[bot] avatar enximi avatar lmaxyz avatar niiightmarexd avatar winestone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

windows-capture's Issues

[BUG πŸͺ²] Graphics Capture Error

Describe the bug πŸ›
Graphics Capture Error

Expected behavior πŸ“
expected no error

OS πŸ€–

  • Version: windows 10
  • Build 22H2

Additional context βž•
My GraphicsCaptureApiHandler implementation:

pub struct WorkerArgs {
    region: Rect<u32>,
    handler: Box<dyn FnMut(&RgbImage) + Send + 'static>,
}

pub struct VideoStreamHandler {
    pub args: WorkerArgs
}

impl GraphicsCaptureApiHandler for VideoStreamHandler {
    type Flags = WorkerArgs;
    type Error = anyhow::Error;

    fn new(flags: Self::Flags) -> std::result::Result<Self, Self::Error> {
        println!("create stream handler");
        Ok(Self {
            args: flags
        })
    }

    fn on_frame_arrived(&mut self, frame: &mut Frame, _capture_control: InternalCaptureControl) -> std::result::Result<(), Self::Error> {
        println!("on frame arrived");
        let width = self.args.region.width;
        let height = self.args.region.height;
        let left = self.args.region.left;
        let top = self.args.region.top;

        let image = RgbImage::from_fn(width, height, |x, y| {
            let mut cropped_image = frame.buffer_crop(
                left,
                top,
                width,
                height
            ).unwrap();

            let index = (y * width + x) as usize;
            let buffer = cropped_image.as_raw_buffer();
            let r = buffer[index * 4];
            let g = buffer[index * 4 + 1];
            let b = buffer[index * 4 + 2];
            Rgb([r, g, b])
        });
        self.args.handler.call_mut((&image,));

        Ok(())
    }
}

It prints create stream handler, but never on frame arrived, and I use start_free_threaded to launch the capture

[BUG πŸͺ²] Doesn't start recording

Describe the bug πŸ›
I executed the example provided in the README.txt but it doesn't start to record anything. It always stays at recording for 0 seconds:

image

Expected behavior πŸ“
The example should work and record a few seconds.

OS πŸ€–

  • latest windows 10 running in a qemu vm

Border

How do i disable the border

How to Start Recording? I'm facing a lot of errors

Hey @NiiightmareXD

I'm using Tauri + NextJS to build a Screen Recorder application using the windows-capture library; I'm new to the Rust language. I created a new file called screen_capture.rs file inside the directory, like this πŸ‘‰ src-tauri/src/screen_capture.rs

I copied the code that you've provided, pasted as it is, and created 2 new functions to "Start the recording" and "Stop the recording"

main.rs

#![cfg_attr(
    all(not(debug_assertions), target_os = "windows"),
    windows_subsystem = "windows"
)]

mod screen_capture;

use tauri::Builder;

fn main() {
    Builder::default()
        .invoke_handler(tauri::generate_handler![
            screen_capture::start_capture, 
            screen_capture::stop_capture
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

screen_capture.rs

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

use windows_capture::{
    capture::GraphicsCaptureApiHandler,
    encoder::{VideoEncoder, VideoEncoderQuality, VideoEncoderType},
    frame::Frame,
    graphics_capture_api::InternalCaptureControl,
    monitor::Monitor,
    settings::{ColorFormat, CursorCaptureSettings, DrawBorderSettings, Settings},
};

// 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 GraphicsCaptureApiHandler for Capture {
    // The type of flags used to get the values from the settings.
    type Flags = String;

    // 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 settings.
    fn new(message: Self::Flags) -> Result<Self, Self::Error> {
        println!("Got The Flag: {message}");

        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.
    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)?;

        // 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()?;

            capture_control.stop();

            // Because there wasn't any new lines in previous prints
            println!();
        }

        Ok(())
    }

    // Optional handler called when the capture item (usually a window) closes.
    fn on_closed(&mut self) -> Result<(), Self::Error> {
        println!("Capture Session Closed");

        Ok(())
    }
}

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

    let settings = Settings::new(
        // Item To Captue
        primary_monitor,
        // Capture Cursor Settings
        CursorCaptureSettings::Default,
        // Draw Borders Settings
        DrawBorderSettings::Default,
        // The desired color format for the captured frame.
        ColorFormat::Rgba8,
        // Additional flags for the capture settings that will be passed to user defined `new` function.
        "Yea This Works".to_string(),
    )
    .unwrap();

    // 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");
}

Below code is for frontend

import {invoke} from "@tauri-apps/api/tauri";

export default function Home() {
   const startRecording = () => {
     invoke("start_capture").catch(console.error);
   };

   const stopRecording = () => {
     invoke("stop_capture").catch(console.error);
   };


  return (
    <div className="flex flex-col items-center justify-center h-screen">
      <div>
        <button onClick={startRecording}>Start Recording</button>
        <button onClick={stopRecording}>Stop Recording</button>
      </div>
    </div>
  );
};

I'm getting a lot of errors in my terminal,

the method `blocking_kind` exists for reference `&Result<(), Box<dyn Error>>`, but its trait bounds were not satisfied
the following trait bounds were not satisfied:
`Box<dyn std::error::Error>: Into<InvokeError>`
which is required by `Result<(), Box<dyn std::error::Error>>: tauri::command::private::ResultKind`
`Result<(), Box<dyn std::error::Error>>: serde::ser::Serialize`
which is required by `&Result<(), Box<dyn std::error::Error>>: tauri::command::private::SerializeKind`

mismatched types
  expected enum `Result<screen_capture::Capture, Box<(dyn std::error::Error + Send + Sync + 'static)>>`
found unit type `()`

unused imports: `Write`, `self`
`#[warn(unused_imports)]` on by default

Thank You

[BUG πŸͺ²]Capture does not end in a multi-threaded scenario.

Describe the bug πŸ›

When using the example, everything is normal. However, when putting Capture::start(settings) into another thread, the capture will not end.

OS πŸ€–

  • Version: 11
  • Build 23H2

Additional context βž•

When I close the captured window, the output "Frame Arrived" will stop, but "Capture Session Closed" and "capture closed" are not being output. The same applies when creating threads using tokio.

use std::thread::sleep;
use std::time::Duration;

use windows_capture::window::Window;
use windows_capture::{
    capture::GraphicsCaptureApiHandler,
    frame::Frame,
    graphics_capture_api::InternalCaptureControl,
    settings::{ColorFormat, CursorCaptureSettings, DrawBorderSettings, Settings},
};

struct Capture {}

impl GraphicsCaptureApiHandler for Capture {
    type Flags = String;

    type Error = Box<dyn std::error::Error + Send + Sync>;

    fn new(message: Self::Flags) -> Result<Self, Self::Error> {
        Ok(Self {})
    }

    fn on_frame_arrived(
        &mut self,
        frame: &mut Frame,
        capture_control: InternalCaptureControl,
    ) -> Result<(), Self::Error> {
        println!("Frame Arrived");
        Ok(())
    }

    fn on_closed(&mut self) -> Result<(), Self::Error> {
        println!("Capture Session Closed");
        Ok(())
    }
}

fn main() {
    let window = Window::from_raw_hwnd(0x000B14CA);

    let settings = Settings::new(
        window,
        CursorCaptureSettings::Default,
        DrawBorderSettings::Default,
        ColorFormat::Rgba8,
        "Yea This Works".to_string(),
    )
    .unwrap();

    std::thread::spawn(move || {
        Capture::start(settings).unwrap();
        println!("capture closed");
    });
    // Capture::start(settings).expect("Screen Capture Failed");

    loop {
        sleep(Duration::from_secs(1));
    }
}

[FEATURE ⭐] Improved guide how to setup library

Is your feature request related to a problem? Please describe. πŸ“
First - thanks for creating this. Faster and more efficient libraries are always a great thing to have.

However. I am not experienced with python and the development process / environment. I just created a few simple scripts for myself that I needed but nothing more. I would like to check if one of my script can use this library instead of dxcam but I have troubles setting it up in PyCharm. When I try to perform the
pip install windows-capture
I get the following error:

Collecting windows-capture
  Using cached windows_capture-1.0.62.tar.gz (35 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  Γ— Preparing metadata (pyproject.toml) did not run successfully.
  β”‚ exit code: 1
  ╰─> [6 lines of output]
     
      Cargo, the Rust package manager, is not installed or is not on PATH.
      This package requires Rust and Cargo to compile extensions. Install it through
      the system's package manager or via https://rustup.rs/
     
      Checking for Rust toolchain....
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

Γ— Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

I tried to install the Rust plugin inside PyCharm and also installing rustup directly on my machine but none of that helped to solve the issue.

Describe the solution you'd like πŸ”‘
A guide, how to properly setup PyCharm (or other environment) to use this library.

⭐ Cross-platform Support

Is your feature request related to a problem? Please describe. πŸ“
Currently, the screen capture Rust crate lacks cross-platform support, limiting its usability across different operating systems. This poses a challenge for developers who are looking to implement screen capture functionality in their applications that need to run seamlessly on diverse platforms.

Describe the solution you'd like πŸ”‘
I propose enhancing the screen capture Rust crate to include robust cross-platform support. This would enable developers to utilize the crate efficiently on various operating systems, such as Windows, macOS, and Linux, without encountering compatibility issues.

Additional context βž•
None

[BUG πŸͺ²]

Describe the bug πŸ›

main panics when I run program with WithoutBorder setting. If I set Default, it works but it has borders, which I dont want to have.

Got The Flag: Yea This Works
thread 'main' panicked at src\commands\record_video.rs:102:26:
Screen Capture Failed: GraphicsCaptureApiError(BorderConfigUnsupported)

Expected behavior πŸ“
To record a video of a screen that lasts 6 seconds

OS πŸ€–
Windows
Version 10.0.19045
Build 19045

Additional context βž•

let settings = Settings::new(
    // Item To Captue
    primary_monitor,
    // Capture Cursor Settings
    CursorCaptureSettings::WithCursor,
    // Draw Borders Settings
    DrawBorderSettings::WithoutBorder,
    // The desired color format for the captured frame.
    ColorFormat::Rgba8,
    // Additional flags for the capture settings that will be passed to user defined `new` function.
    "Yea This Works".to_string(),
)
.unwrap();

[BUG πŸͺ²] When the window is not maximized, the obtained image is incorrect.

Describe the bug πŸ›
When the window is not maximized, the obtained image is incorrect.

Expected behavior πŸ“
Correctly capture windows without maximizing them.

OS πŸ€–

  • Version: [Windows 11]
  • Build[23H2]

Additional context βž•
This is an image captured using windows-capture when the control panel window is not maximized.
img1
This is the correct image captured using other screenshot tool.
img2
If the window is maximized, then windows-capture can capture the correct image.
This is an image obtained when the control panel window is maximized.
img3

My code is as follows. Compared with the example, I only modified the window to be captured. I have also run it using the foreground window. I ran it in RustRoverο»Ώ, so the captured window is RustRover's windowο»Ώ. When the RustRover ο»Ώwindow is not maximized, the obtained image will also be distorted like what was described above.

use windows::Win32::Foundation::HWND;
use windows_capture::{
    capture::WindowsCaptureHandler,
    frame::{Frame, ImageFormat},
    graphics_capture_api::InternalCaptureControl,
    settings::{ColorFormat, Settings},
    window::Window,
};

struct Capture;

impl WindowsCaptureHandler for Capture {
    type Flags = String;

    type Error = Box<dyn std::error::Error + Send + Sync>;

    fn new(message: Self::Flags) -> Result<Self, Self::Error> {
        println!("Got The Flag: {message}");

        Ok(Self {})
    }

    fn on_frame_arrived(
        &mut self,
        frame: &mut Frame,
        capture_control: InternalCaptureControl,
    ) -> Result<(), Self::Error> {
        println!("New Frame Arrived");

        frame.save_as_image("image3.png", ImageFormat::Png)?;

        capture_control.stop();

        Ok(())
    }

    fn on_closed(&mut self) -> Result<(), Self::Error> {
        println!("Capture Session Closed");

        Ok(())
    }
}

fn main() {
    let my_window = Window::from_raw_hwnd(HWND(0x000A0B8E));

    let settings = Settings::new(
        my_window,
        Some(true),
        None,
        ColorFormat::Rgba8,
        "It Works".to_string(),
    )
    .unwrap();

    Capture::start(settings).expect("Screen Capture Failed");
}

Request help for a conditional capture of a single image

I encountered some problems in the call, perhaps the encapsulated function does not match my task, the scenario is as follows: I want a control function condition is true to intercept the desktop, is false to suspend the intercept, do not need to repeat the initialization operation, what should I do to complete this task?

Expose Capture::GraphicsCaptureSession::IsSupported()

Hello, I'm making a cross-platform screen capture library and one thing that will be very useful is if the Capture::GraphicsCaptureSession::IsSupported() is exposed from within this crate. It would allow me to entirely omit my dependency on the windows::Graphics::Capture module and use windows-capture for everything πŸ™Œ

This would allow developers to check for API support independently instead of accounting for an error during capture.

I'm happy to make a PR for this if you let me know where to start.

Thanks for the fab work! 🌟

[BUG πŸͺ²] Python version returns error when trying to start a WindowsCapture

Describe the bug πŸ›
After freshly installing the library using the pip command, trying to run the example code of the Python version of the library returns the following error:
Exception: Capture Session Threw An Exception -> Failed To Initialize WinRT

On line: capture.start()

I didn't had rust installed in the system but it did not work even after installing it (if that was even a requirement, which I don't know)

Expected behavior πŸ“
The script should start storing frames as the screen's content changes.

OS πŸ€–

  • Version: Windows 11
  • Build 22H2 Insider Pro

[BUG πŸͺ²] window capture getting pink color output in the recorded video

Describe the bug πŸ›

use std::{
    any::Any,
    io::{self, Write},
    time::Instant,
};

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

// 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 GraphicsCaptureApiHandler for Capture {
    // The type of flags used to get the values from the settings.
    type Flags = String;

    // 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 settings.
    fn new(message: Self::Flags) -> Result<Self, Self::Error> {
        println!("Got The Flag: {message}");

        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.
    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)?;

        // 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()?;

            capture_control.stop();

            // Because there wasn't any new lines in previous prints
            println!();
        }

        Ok(())
    }

    // Optional handler called when the capture item (usually a window) closes.
    fn on_closed(&mut self) -> Result<(), Self::Error> {
        println!("Capture Session Closed");

        Ok(())
    }
}

fn main() {
    // Gets The Foreground Window, Checkout The Docs For Other Capture Items
    let primary_monitor = Monitor::primary().expect("There is no primary monitor");
    print!(
        "\rPrimary Monitor: {}",
        primary_monitor.name().unwrap_or_default()
    );

    let window_to_capture = Window::from_contains_name("Visual Studio Code")
        .expect("There is no window with that name");

    // print!("\rWindow to Capture: {}", window_to_capture.try_into().unwrap());

    let settings = Settings::new(
        // Item To Captue
        window_to_capture,
        // primary_monitor,
        // Capture Cursor Settings
        CursorCaptureSettings::Default,
        // Draw Borders Settings
        DrawBorderSettings::Default,
        // The desired color format for the captured frame.
        ColorFormat::Rgba8,
        // Additional flags for the capture settings that will be passed to user defined `new` function.
        "Yea This Works".to_string(),
    )
    .unwrap();

    // 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");
}


I changed this part

 let window_to_capture = Window::from_contains_name("Visual Studio Code")
        .expect("There is no window with that name");

image

but when i give primary monitor thing it works fine ,

Expected behavior πŸ“
LIke monitor it should work like normal

OS πŸ€–

Edition Windows 11 Pro
Version 23H2
Installed on β€Ž12-β€Ž08-β€Ž2023
OS build 22631.3447
Experience Windows Feature Experience Pack 1000.22688.1000.0

Additional context βž•
Add any other context about the problem here.

[BUG πŸͺ²] Capture Session Threw An Exception -> Graphics Capture Error

Describe the bug πŸ›

Traceback (most recent call last):
  File "C:\Repos\yolov5\detect.py", line 51, in <module>
    from models.common import DetectMultiBackend
  File "C:\Repos\yolov5\models\common.py", line 41, in <module>
    from utils.dataloaders import exif_transpose, letterbox
  File "C:\Repos\yolov5\utils\dataloaders.py", line 70, in <module>
    capture.start()
  File "C:\Users\Ryan\AppData\Local\Programs\Python\Python310\lib\site-packages\windows_capture\__init__.py", line 204, in start
    self.capture.start()
Exception: Capture Session Threw An Exception -> Graphics Capture Error

Expected behavior πŸ“
It captures the screen

OS πŸ€–
Edition Windows 10 Pro
Version 22H2
Installed on β€Ž12/β€Ž22/β€Ž2022
OS build 19045.3570
Experience Windows Feature Experience Pack 1000.19052.1000.0

Additional context βž•
This works on windows 11, interestingly enough https://github.com/rlewkowicz/Win32CaptureSample works on 10, but not 11 (in weird ways).

OBS works on both using the same underlying apis. There has to be some nuanced difference in the core apis.

[BUG πŸͺ²] Error while installing with pip

Describe the bug πŸ›
While trying to install the library with pip install windows-capture, I got the following error:

C:\Users\Andre.LAPTOP01>pip install windows-capture
WARNING: Ignoring invalid distribution -illow (c:\users\andre.laptop01\appdata\local\programs\python\python310\lib\site-packages)
Collecting windows-capture
  Using cached windows_capture-1.0.42.tar.gz (33 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  Γ— Preparing metadata (pyproject.toml) did not run successfully.
  β”‚ exit code: 1
  ╰─> [10 lines of output]
      error: failed to parse lock file at: C:\Users\Andre.LAPTOP01\AppData\Local\Temp\pip-install-ufh0qrqo\windows-capture_da4973df594a487dacd1b381176f7e6a\windows-capture-python\Cargo.lock

      Caused by:
        package `windows-capture` is specified twice in the lockfile
      ðŸ’Β₯ maturin failed
        Caused by: Cargo metadata failed. Does your crate compile with `cargo build`?
        Caused by: `cargo metadata` exited with an error:
      Error running maturin: Command '['maturin', 'pep517', 'write-dist-info', '--metadata-directory', 'C:\\Users\\Andre.LAPTOP01\\AppData\\Local\\Temp\\pip-modern-metadata-vd2ex463', '--interpreter', 'C:\\Users\\Andre.LAPTOP01\\AppData\\Local\\Programs\\Python\\Python310\\python.exe']' returned non-zero exit status 1.
      Checking for Rust toolchain....
      Running `maturin pep517 write-dist-info --metadata-directory C:\Users\Andre.LAPTOP01\AppData\Local\Temp\pip-modern-metadata-vd2ex463 --interpreter C:\Users\Andre.LAPTOP01\AppData\Local\Programs\Python\Python310\python.exe`
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

Γ— Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

Expected behavior πŸ“
Instalation successful

OS πŸ€–

  • Version: [e.g. 11]
  • Build[e.g. 22H2]

Additional context βž•
Add any other context about the problem here.

[FEATURE ⭐]

I want to add a method to the window object so that it can recognize window handles obtained by external programs, this may not be a good practice, but I need it, if there is a better way to recognize the same HWND between different languages, please provide it

pub fn from_process_id(process_id: u32) -> Result<Self, Error> {
let windows = Self::enumerate()?;
let target_window = windows.into_iter().find(|window| {
let mut window_pid: u32 = 0;
unsafe {
GetWindowThreadProcessId(window.window, Some(&mut window_pid));
}
window_pid == process_id && unsafe { IsWindowVisible(window.window) }.as_bool()
});
target_window.map_or_else(|| Err(Error::NotFound(process_id.to_string())), Ok)
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.