Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This implementation works by target window but couldn't identify target dimensions #3

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
329 changes: 290 additions & 39 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ categories = ["graphics", "multimedia", "multimedia::video"]

[dependencies]
sysinfo = "0.30.0"
image = "0.24.7"

[target.'cfg(target_os = "windows")'.dependencies]
windows-capture = "1.3.2"
Expand All @@ -36,4 +37,4 @@ objc = "0.2.7"
[target.'cfg(target_os = "linux")'.dependencies]
pipewire = "0.8.0"
dbus = "0.9.7"
rand = "0.8.5"
rand = "0.8.5"
Binary file added captured_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 29 additions & 22 deletions src/capturer/engine/mac/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,15 @@ impl StreamOutput for Capturer {
}
}

pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> Result<SCStream, String> {
// If no target is specified, capture the main display
let target = options
.target
.clone()
.unwrap_or_else(|| Target::Display(targets::get_main_display()));

println!("Debug: Selected target: {:?}", target);

let sc_shareable_content = SCShareableContent::current();

let params = match target {
Expand All @@ -107,10 +109,11 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
.windows
.into_iter()
.find(|sc_win| sc_win.window_id == window.id)
.unwrap();
.ok_or_else(|| format!("Window with id {} not found", window.id))?;

println!("Debug: Found SCWindow: {:?}", sc_window);

// Return a DesktopIndependentWindow
// https://developer.apple.com/documentation/screencapturekit/sccontentfilter/3919804-init
InitParams::DesktopIndependentWindow(sc_window)
}
Target::Display(display) => {
Expand All @@ -119,7 +122,9 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
.displays
.into_iter()
.find(|sc_dis| sc_dis.display_id == display.id)
.unwrap();
.ok_or_else(|| format!("Display with id {} not found", display.id))?;

println!("Debug: Found SCDisplay: {:?}", sc_display);

match &options.excluded_targets {
None => InitParams::Display(sc_display),
Expand All @@ -129,14 +134,8 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
.into_iter()
.filter(|window| {
excluded_targets
.into_iter()
.find(|excluded_target| match excluded_target {
Target::Window(excluded_window) => {
excluded_window.id == window.window_id
}
_ => false,
})
.is_some()
.iter()
.any(|excluded_target| matches!(excluded_target, Target::Window(excluded_window) if excluded_window.id == window.window_id))
})
.collect();

Expand Down Expand Up @@ -170,6 +169,15 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {

let [width, height] = get_output_frame_size(options);

// Ensure width and height are not zero. This ensures that we always have a valid width and height for the stream configuration.
let width = width.max(1);
let height = height.max(1);

println!("Debug: width = {}, height = {}", width, height);
println!("Debug: source_rect = {:?}", source_rect);
println!("Debug: pixel_format = {:?}", pixel_format);
println!("Debug: fps = {}", options.fps);

let stream_config = SCStreamConfiguration {
width,
height,
Expand All @@ -191,7 +199,7 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<Frame>) -> SCStream {
SCStreamOutputType::Screen,
);

stream
Ok(stream)
}

pub fn get_output_frame_size(options: &Options) -> [u32; 2] {
Expand All @@ -205,23 +213,21 @@ pub fn get_output_frame_size(options: &Options) -> [u32; 2] {

// Calculate the output height & width based on the required resolution
// Output width and height need to be multiplied by scale (or dpi)
let mut output_width = (source_rect.size.width as u32) * (scale_factor as u32);
let mut output_height = (source_rect.size.height as u32) * (scale_factor as u32);
// 1200x800
let mut output_width = (source_rect.size.width as u32).max(4000) * (scale_factor as u32);
let mut output_height = (source_rect.size.height as u32).max(4000) * (scale_factor as u32);

match options.output_resolution {
Resolution::Captured => {}
_ => {
let [resolved_width, resolved_height] = options
.output_resolution
.value((source_rect.size.width as f32) / (source_rect.size.height as f32));
// 1280 x 853
output_width = cmp::min(output_width, resolved_width);
output_height = cmp::min(output_height, resolved_height);
output_width = cmp::min(output_width, resolved_width).max(4000);
output_height = cmp::min(output_height, resolved_height).max(4000);
}
}

output_width -= output_width % 2;
output_height -= output_height % 2;
println!("Debug: Calculated output frame size: width = {}, height = {}", output_width, output_height);

[output_width, output_height]
}
Expand All @@ -233,6 +239,7 @@ pub fn get_crop_area(options: &Options) -> Area {
.unwrap_or_else(|| Target::Display(targets::get_main_display()));

let (width, height) = targets::get_target_dimensions(&target);
println!("Debug: Target dimensions: width = {}, height = {}", width, height);

options
.crop_area
Expand All @@ -259,4 +266,4 @@ pub fn get_crop_area(options: &Options) -> Area {
height: height as f64,
},
})
}
}
29 changes: 18 additions & 11 deletions src/capturer/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,40 +25,47 @@ pub struct Engine {
}

impl Engine {
pub fn new(options: &Options, tx: mpsc::Sender<Frame>) -> Engine {
pub fn new(options: &Options, tx: mpsc::Sender<Frame>) -> Result<Engine, String> {
#[cfg(target_os = "macos")]
{
let mac = mac::create_capturer(&options, tx);
return Engine {
let mac = mac::create_capturer(&options, tx)?;
return Ok(Engine {
mac,
options: (*options).clone(),
};
});
}

#[cfg(target_os = "windows")]
{
let win = win::create_capturer(&options, tx);
return Engine {
return Ok(Engine {
win,
options: (*options).clone(),
};
});
}

#[cfg(target_os = "linux")]
{
let linux = linux::create_capturer(&options, tx);
return Engine {
return Ok(Engine {
linux,
options: (*options).clone(),
};
});
}
}

pub fn start(&mut self) {
#[cfg(target_os = "macos")]
{
// self.mac.add_output(Capturer::new(tx));
self.mac.start_capture().expect("Failed to start capture");
match self.mac.start_capture() {
Ok(_) => println!("Capture started successfully"),
Err(e) => {
eprintln!("Failed to start capture: {:?}", e);
if let Some(error_code) = e.to_string().split(':').next() {
eprintln!("Error code: {}", error_code);
}
}
}
}

#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -105,4 +112,4 @@ impl Engine {
return [0, 0];
}
}
}
}
8 changes: 4 additions & 4 deletions src/capturer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ pub struct Capturer {

impl Capturer {
/// Create a new capturer instance with the provided options
pub fn new(options: Options) -> Capturer {
pub fn new(options: Options) -> Result<Capturer, String> {
let (tx, rx) = mpsc::channel::<Frame>();
let engine = engine::Engine::new(&options, tx);
let engine = engine::Engine::new(&options, tx)?;

Capturer { engine, rx }
Ok(Capturer { engine, rx })
}

// TODO
Expand All @@ -103,4 +103,4 @@ impl Capturer {
pub fn get_output_frame_size(&mut self) -> [u32; 2] {
self.engine.get_output_frame_size()
}
}
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod utils;
// Helper Methods
pub use targets::get_all_targets;
pub use targets::Target;
pub use targets::Window;
pub use utils::has_permission;
pub use utils::is_supported;
pub use utils::request_permission;
pub use utils::request_permission;
Loading