Skip to content

Commit 454acf6

Browse files
committed
handle macos stream errors with error flag
1 parent b1e140a commit 454acf6

File tree

3 files changed

+41
-7
lines changed

3 files changed

+41
-7
lines changed

src/capturer/engine/mac/mod.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use std::cmp;
1+
use std::sync::atomic::AtomicBool;
22
use std::sync::mpsc;
3+
use std::{cmp, sync::Arc};
34

45
use pixelformat::get_pts_in_nanoseconds;
56
use screencapturekit::{
@@ -31,10 +32,15 @@ mod pixelformat;
3132

3233
pub use pixel_buffer::PixelBuffer;
3334

34-
struct ErrorHandler;
35+
struct ErrorHandler {
36+
error_flag: Arc<AtomicBool>,
37+
}
38+
3539
impl StreamErrorHandler for ErrorHandler {
3640
fn on_error(&self) {
37-
println!("Error!");
41+
eprintln!("Screen capture error occurred.");
42+
self.error_flag
43+
.store(true, std::sync::atomic::Ordering::Relaxed);
3844
}
3945
}
4046

@@ -54,7 +60,11 @@ impl StreamOutput for Capturer {
5460
}
5561
}
5662

57-
pub fn create_capturer(options: &Options, tx: mpsc::Sender<ChannelItem>) -> SCStream {
63+
pub fn create_capturer(
64+
options: &Options,
65+
tx: mpsc::Sender<ChannelItem>,
66+
error_flag: Arc<AtomicBool>,
67+
) -> SCStream {
5868
// If no target is specified, capture the main display
5969
let target = options
6070
.target
@@ -147,7 +157,7 @@ pub fn create_capturer(options: &Options, tx: mpsc::Sender<ChannelItem>) -> SCSt
147157
..Default::default()
148158
};
149159

150-
let mut stream = SCStream::new(filter, stream_config, ErrorHandler);
160+
let mut stream = SCStream::new(filter, stream_config, ErrorHandler { error_flag });
151161
stream.add_output(Capturer::new(tx), SCStreamOutputType::Screen);
152162

153163
stream

src/capturer/engine/mac/pixel_buffer.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,26 @@ impl<'a> Drop for PixelBufferData<'a> {
166166
impl RawCapturer<'_> {
167167
#[cfg(target_os = "macos")]
168168
pub fn get_next_pixel_buffer(&self) -> Result<PixelBuffer, mpsc::RecvError> {
169+
use std::time::Duration;
170+
171+
let capturer = &self.capturer;
172+
169173
loop {
170-
if let Some(frame) = PixelBuffer::new(self.capturer.rx.recv()?) {
174+
let error_flag = capturer
175+
.engine
176+
.error_flag
177+
.load(std::sync::atomic::Ordering::Relaxed);
178+
if error_flag {
179+
return Err(mpsc::RecvError);
180+
}
181+
182+
let res = match capturer.rx.recv_timeout(Duration::from_millis(1)) {
183+
Ok(v) => Ok(v),
184+
Err(mpsc::RecvTimeoutError::Timeout) => continue,
185+
Err(mpsc::RecvTimeoutError::Disconnected) => Err(mpsc::RecvError),
186+
}?;
187+
188+
if let Some(frame) = PixelBuffer::new(res) {
171189
return Ok(frame);
172190
}
173191
}

src/capturer/engine/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ pub fn get_output_frame_size(options: &Options) -> [u32; 2] {
4040

4141
pub struct Engine {
4242
options: Options,
43+
4344
#[cfg(target_os = "macos")]
4445
mac: screencapturekit::sc_stream::SCStream,
46+
#[cfg(target_os = "macos")]
47+
error_flag: std::sync::Arc<std::sync::atomic::AtomicBool>,
4548

4649
#[cfg(target_os = "windows")]
4750
win: win::WCStream,
@@ -54,9 +57,12 @@ impl Engine {
5457
pub fn new(options: &Options, tx: mpsc::Sender<ChannelItem>) -> Engine {
5558
#[cfg(target_os = "macos")]
5659
{
57-
let mac = mac::create_capturer(options, tx);
60+
let error_flag = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
61+
let mac = mac::create_capturer(options, tx, error_flag.clone());
62+
5863
Engine {
5964
mac,
65+
error_flag,
6066
options: (*options).clone(),
6167
}
6268
}

0 commit comments

Comments
 (0)