diff --git a/src/capturer/engine/mac/mod.rs b/src/capturer/engine/mac/mod.rs index bea876f..9876ef4 100644 --- a/src/capturer/engine/mac/mod.rs +++ b/src/capturer/engine/mac/mod.rs @@ -11,9 +11,10 @@ use screencapturekit::{ sc_stream_configuration::{PixelFormat, SCStreamConfiguration}, sc_types::SCFrameStatus, }; +use screencapturekit_sys::os_types::base::{CMTime, CMTimeScale}; use screencapturekit_sys::os_types::geometry::{CGPoint, CGRect, CGSize}; -use crate::capturer::{Area, Options, Point, Size}; +use crate::{capturer::{Area, Options, Point, Size}, frame::BGRAFrame}; use crate::frame::{Frame, FrameType}; use crate::targets::Target; use crate::{capturer::Resolution, targets}; @@ -45,28 +46,43 @@ impl StreamOutput for Capturer { let frame_status = &sample.frame_status; match frame_status { - SCFrameStatus::Complete => unsafe { - let frame; - match self.output_type { + SCFrameStatus::Complete | SCFrameStatus::Started => unsafe { + let frame = match self.output_type { FrameType::YUVFrame => { let yuvframe = pixelformat::create_yuv_frame(sample).unwrap(); - frame = Frame::YUVFrame(yuvframe); + Frame::YUVFrame(yuvframe) } FrameType::RGB => { let rgbframe = pixelformat::create_rgb_frame(sample).unwrap(); - frame = Frame::RGB(rgbframe); + Frame::RGB(rgbframe) } FrameType::BGR0 => { let bgrframe = pixelformat::create_bgr_frame(sample).unwrap(); - frame = Frame::BGR0(bgrframe); + Frame::BGR0(bgrframe) } FrameType::BGRAFrame => { let bgraframe = pixelformat::create_bgra_frame(sample).unwrap(); - frame = Frame::BGRA(bgraframe); + Frame::BGRA(bgraframe) } - } + }; self.tx.send(frame).unwrap_or(()); }, + SCFrameStatus::Idle => { + // Quick hack - just send an empty frame, and the caller can figure out how to handle it + match self.output_type { + FrameType::BGRAFrame => { + let display_time = sample.sys_ref.get_presentation_timestamp().value as u64; + let frame = BGRAFrame { + display_time, + width: 0, + height: 0, + data: vec![], + }; + self.tx.send(Frame::BGRA(frame)).unwrap_or(()); + }, + _ => {} + } + }, _ => {} } } @@ -160,6 +176,12 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender) -> SCStream { source_rect, pixel_format, shows_cursor: options.show_cursor, + minimum_frame_interval: CMTime { + value: 1, + timescale: options.fps as CMTimeScale, + epoch: 0, + flags: 1, + }, ..Default::default() }; @@ -183,8 +205,8 @@ 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; + 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 match options.output_resolution { Resolution::Captured => {} diff --git a/src/main.rs b/src/main.rs index 4446323..46d09f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,22 +24,12 @@ fn main() { } } - // Get recording targets - let targets = scap::get_all_targets(); - println!("🎯 Targets: {:?}", targets); - - let vscode_win = targets - .into_iter() - .find(|target| match target { - Target::Display(_) => false, - Target::Window(w) => w.title.contains("Visual Studio Code"), - }) - .expect("Visual Studio Code window not found"); + // // Get recording targets + // let targets = scap::get_all_targets(); // Create Options let options = Options { fps: 60, - target: Some(vscode_win), show_cursor: true, show_highlight: true, excluded_targets: None,