-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy path12_stream_updates.rs
More file actions
134 lines (110 loc) · 4.26 KB
/
Copy path12_stream_updates.rs
File metadata and controls
134 lines (110 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Dynamic Stream Updates
//!
//! Demonstrates updating a running stream's configuration and content filter.
//! This example shows:
//! - Updating stream configuration while capturing (resolution, frame rate)
//! - Switching capture source via content filter update
//! - Using the synchronization clock for A/V sync
//! - Stream delegate for error handling
//!
//! Run with: `cargo run --example 12_stream_updates --features macos_14_0`
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");
// 1. Get available content
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());
// 2. Initial configuration - low resolution
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");
// 3. Create and start stream
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");
// 4. Check synchronization clock (macOS 13.0+)
#[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);
}
// Capture at low resolution for 2 seconds
std::thread::sleep(Duration::from_secs(2));
let frames_low = count.load(Ordering::Relaxed);
println!("📊 Frames at 640x480: {frames_low}");
// 5. Update configuration to higher resolution
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:?}"),
}
// Capture at high resolution for 2 seconds
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
);
// 6. Update content filter (switch to window if available)
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
);
}
// 7. Stop capture
stream.stop_capture()?;
println!("\n⏹️ Capture stopped");
println!(
"✅ Total frames captured: {}",
count.load(Ordering::Relaxed)
);
Ok(())
}