screencapturekit-rs
screencapturekit-rs copied to clipboard
Hi, there. Why I always get the dimensions: 1920 x 1080?
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
}
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?
Is this still an issue?