screencapturekit-rs icon indicating copy to clipboard operation
screencapturekit-rs copied to clipboard

Hi, there. Why I always get the dimensions: 1920 x 1080?

Open qzd1989 opened this issue 7 months ago • 1 comments

Thank you, sir. I need help, does here have a discord channel to comunicate?

My Os Display Information

# system_profiler SPDisplaysDataType
Graphics/Displays:
    Apple M1 Max:
      Chipset Model: Apple M1 Max
      Type: GPU
      Bus: Built-In
      Total Number of Cores: 32
      Vendor: Apple (0x106b)
      Metal Support: Metal 3
      Displays:
        Color LCD:
          Display Type: Built-in Liquid Retina XDR Display
          Resolution: 3456 x 2234 Retina
          Main Display: Yes
          Mirror: Off
          Online: Yes
          Automatically Adjust Brightness: No
          Connection Type: Internal
        PHL 288E2:
          Resolution: 3200 x 1800 (QHD+ - Wide Quad Extended Graphics Array Plus)
          UI Looks like: 1600 x 900 @ 60.00Hz
          Mirror: Off
          Online: Yes
          Rotation: Supported
        VA2478-H-2:
          Resolution: 1600 x 900
          UI Looks like: 1600 x 900 @ 60.00Hz
          Mirror: Off
          Online: Yes
          Rotation: Supported

I have three displays:

// dbg!(Vec<SCDisplay>): 
    SCDisplay {
        display_id: 5,
        frame: CGRect {
            origin: CGPoint {
                x: 3328.0,
                y: 0.0,
            },
            size: CGSize {
                width: 1600.0,
                height: 900.0,
            },
        },
        width: 1600,
        height: 900,
    },
    SCDisplay {
        display_id: 1,
        frame: CGRect {
            origin: CGPoint {
                x: 0.0,
                y: 0.0,
            },
            size: CGSize {
                width: 1728.0,
                height: 1117.0,
            },
        },
        width: 1728,
        height: 1117,
    },
    SCDisplay {
        display_id: 4,
        frame: CGRect {
            origin: CGPoint {
                x: 1728.0,
                y: 0.0,
            },
            size: CGSize {
                width: 1600.0,
                height: 900.0,
            },
        },
        width: 1600,
        height: 900,
    },

my example code is:

use core_foundation::error::CFError;
use core_media_rs::cm_sample_buffer::CMSampleBuffer;
use image::{ImageBuffer, Rgba};
use screencapturekit::{
    output::LockTrait,
    shareable_content::SCShareableContent,
    stream::{
        configuration::{pixel_format::PixelFormat, SCStreamConfiguration},
        content_filter::SCContentFilter,
        output_trait::SCStreamOutputTrait,
        output_type::SCStreamOutputType,
        SCStream,
    },
};
use std::{
    sync::mpsc::{channel, Sender},
    thread,
    time::Duration,
};
struct ScreenStreamOutput {
    sender: Sender<CMSampleBuffer>,
}
impl SCStreamOutputTrait for ScreenStreamOutput {
    fn did_output_sample_buffer(
        &self,
        sample_buffer: CMSampleBuffer,
        _of_type: SCStreamOutputType,
    ) {
        self.sender
            .send(sample_buffer)
            .expect("could not send to output_buffer");
    }
}
fn main() -> Result<(), CFError> {
    let (tx, rx) = channel();
    let stream = get_stream(tx)?;
    stream.start_capture()?;
    let max_number_of_samples: i32 = 400000;
    for sample_index in 0..max_number_of_samples {
        println!("sample_index={}", sample_index);
        let sample = rx
            .recv_timeout(std::time::Duration::from_secs(10))
            .expect("could not receive from output_buffer");
        if let Ok(buffer) = sample.get_pixel_buffer() {
            dbg!((
                sample.get_format_description().unwrap(),
                buffer.get_plane_count(),
                buffer.get_bytes_per_row_of_plane(0),
                (buffer.get_width(), buffer.get_height()) //always be 1920 x 1080
            ));
            let guard = buffer.lock().unwrap();
            let rgba_data = bgra_to_rgba(guard.as_slice());
            let img = ImageBuffer::<Rgba<u8>, _>::from_raw(
                buffer.get_width(),
                buffer.get_height(),
                rgba_data,
            )
            .unwrap();
            img.save("b.png").unwrap();
            break;
        }
    }
    stream.stop_capture().ok();
    thread::sleep(Duration::from_secs(1));
    Ok(())
}
fn get_stream(tx: Sender<CMSampleBuffer>) -> Result<SCStream, CFError> {
    let displays = SCShareableContent::get().unwrap().displays();
    dbg!(&displays);
    let display = displays.into_iter().find(|x| x.display_id() == 1).unwrap(); //no matter I set 1 or 4 or 5
    dbg!((display.width(), display.height()));
    let config = SCStreamConfiguration::new()
        .set_captures_audio(false)?
        .set_pixel_format(PixelFormat::BGRA)?; // if I set_width(display.width()) or set_height(display_height()) or both here, the saved image is corrupted and shows garbled content.
    let filter = SCContentFilter::new().with_display_excluding_windows(&display, &[]);
    let mut stream = SCStream::new(&filter, &config);
    stream.add_output_handler(
        ScreenStreamOutput { sender: tx },
        SCStreamOutputType::Screen,
    );
    Ok(stream)
}
fn bgra_to_rgba(bgra_data: &[u8]) -> Vec<u8> {
    let mut rgba_data = Vec::with_capacity(bgra_data.len());
    for chunk in bgra_data.chunks_exact(4) {
        let b = chunk[0];
        let g = chunk[1];
        let r = chunk[2];
        let a = chunk[3];
        rgba_data.extend_from_slice(&[r, g, b, a]);
    }
    rgba_data
}

qzd1989 avatar May 12 '25 15:05 qzd1989

I don't understand....why it works and return the right dimensions now? I didn't change anything.... does there have any cache or something?

qzd1989 avatar May 12 '25 17:05 qzd1989

Is this still an issue?

1313 avatar Jun 07 '25 16:06 1313