use screencapturekit::prelude::*;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;
struct FrameHandler {
count: Arc<AtomicUsize>,
}
impl SCStreamOutputTrait for FrameHandler {
fn did_output_sample_buffer(&self, _sample: CMSampleBuffer, of_type: SCStreamOutputType) {
if matches!(of_type, SCStreamOutputType::Screen) {
self.count.fetch_add(1, Ordering::Relaxed);
}
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("đ Dynamic Stream Updates\n");
let content = SCShareableContent::get()?;
let displays = content.displays();
if displays.is_empty() {
println!("â ī¸ Need at least 1 display for this example");
return Ok(());
}
let display = &displays[0];
println!("đē Using display: {}x{}", display.width(), display.height());
let filter = SCContentFilter::create()
.with_display(display)
.with_excluding_windows(&[])
.build();
let config = SCStreamConfiguration::new()
.with_width(640)
.with_height(480)
.with_pixel_format(PixelFormat::BGRA);
println!("đ Initial config: 640x480");
let count = Arc::new(AtomicUsize::new(0));
let handler = FrameHandler {
count: count.clone(),
};
let mut stream = SCStream::new(&filter, &config);
stream.add_output_handler(handler, SCStreamOutputType::Screen);
stream.start_capture()?;
println!("âļī¸ Capture started\n");
#[cfg(feature = "macos_13_0")]
if let Some(clock) = stream.synchronization_clock() {
println!("âąī¸ Sync clock available:");
let time = clock.time();
println!(" Current time: {}/{} seconds", time.value, time.timescale);
}
std::thread::sleep(Duration::from_secs(2));
let frames_low = count.load(Ordering::Relaxed);
println!("đ Frames at 640x480: {frames_low}");
println!("\nđ Updating to 1920x1080...");
let new_config = SCStreamConfiguration::new()
.with_width(1920)
.with_height(1080)
.with_pixel_format(PixelFormat::BGRA);
match stream.update_configuration(&new_config) {
Ok(()) => println!("â
Configuration updated"),
Err(e) => println!("â Update failed: {e:?}"),
}
std::thread::sleep(Duration::from_secs(2));
let frames_high = count.load(Ordering::Relaxed);
println!(
"đ Frames at 1920x1080: {} (total: {})",
frames_high - frames_low,
frames_high
);
let windows = content.windows();
if let Some(window) = windows.iter().find(|w| w.is_on_screen()) {
println!("\nđ Switching to window capture...");
println!(" Window: {}", window.title().unwrap_or_default());
let window_filter = SCContentFilter::create().with_window(window).build();
match stream.update_content_filter(&window_filter) {
Ok(()) => println!("â
Filter updated to window"),
Err(e) => println!("â Filter update failed: {e:?}"),
}
std::thread::sleep(Duration::from_secs(2));
let frames_window = count.load(Ordering::Relaxed);
println!(
"đ Frames from window: {} (total: {})",
frames_window - frames_high,
frames_window
);
}
stream.stop_capture()?;
println!("\nâšī¸ Capture stopped");
println!(
"â
Total frames captured: {}",
count.load(Ordering::Relaxed)
);
Ok(())
}