screencapturekit/stream/configuration/
audio.rs

1//! Audio capture configuration
2//!
3//! Methods for configuring audio capture, sample rate, and channel count.
4
5use crate::utils::ffi_string::{ffi_string_from_buffer, SMALL_BUFFER_SIZE};
6
7use super::internal::SCStreamConfiguration;
8
9impl SCStreamConfiguration {
10    /// Enable or disable audio capture
11    ///
12    /// # Examples
13    ///
14    /// ```
15    /// use screencapturekit::prelude::*;
16    ///
17    /// let mut config = SCStreamConfiguration::default();
18    /// config.set_captures_audio(true);
19    /// assert!(config.get_captures_audio());
20    /// ```
21    pub fn set_captures_audio(&mut self, captures_audio: bool) {
22        unsafe {
23            crate::ffi::sc_stream_configuration_set_captures_audio(self.as_ptr(), captures_audio);
24        }
25    }
26
27    /// Check if audio capture is enabled
28    pub fn get_captures_audio(&self) -> bool {
29        unsafe { crate::ffi::sc_stream_configuration_get_captures_audio(self.as_ptr()) }
30    }
31
32    /// Set the audio sample rate in Hz
33    ///
34    /// Common values: 44100, 48000
35    ///
36    /// # Examples
37    ///
38    /// ```
39    /// use screencapturekit::prelude::*;
40    ///
41    /// let mut config = SCStreamConfiguration::default();
42    /// config.set_sample_rate(48000);
43    /// assert_eq!(config.get_sample_rate(), 48000);
44    /// ```
45    pub fn set_sample_rate(&mut self, sample_rate: i32) {
46        unsafe {
47            crate::ffi::sc_stream_configuration_set_sample_rate(
48                self.as_ptr(),
49                sample_rate as isize,
50            );
51        }
52    }
53
54    /// Get the configured audio sample rate
55    pub fn get_sample_rate(&self) -> i32 {
56        // FFI returns isize but sample rate fits in i32 (typical values: 44100, 48000)
57        #[allow(clippy::cast_possible_truncation)]
58        unsafe {
59            crate::ffi::sc_stream_configuration_get_sample_rate(self.as_ptr()) as i32
60        }
61    }
62
63    /// Set the number of audio channels
64    ///
65    /// Common values: 1 (mono), 2 (stereo)
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use screencapturekit::prelude::*;
71    ///
72    /// let mut config = SCStreamConfiguration::default();
73    /// config.set_channel_count(2); // Stereo
74    /// assert_eq!(config.get_channel_count(), 2);
75    /// ```
76    pub fn set_channel_count(&mut self, channel_count: i32) {
77        unsafe {
78            crate::ffi::sc_stream_configuration_set_channel_count(
79                self.as_ptr(),
80                channel_count as isize,
81            );
82        }
83    }
84
85    /// Get the configured channel count
86    pub fn get_channel_count(&self) -> i32 {
87        // FFI returns isize but channel count fits in i32 (typical values: 1-8)
88        #[allow(clippy::cast_possible_truncation)]
89        unsafe {
90            crate::ffi::sc_stream_configuration_get_channel_count(self.as_ptr()) as i32
91        }
92    }
93
94    /// Enable microphone capture (macOS 15.0+)
95    ///
96    /// When set to `true`, the stream will capture audio from the microphone
97    /// in addition to system/application audio (if `captures_audio` is also enabled).
98    ///
99    /// **Note**: Requires `NSMicrophoneUsageDescription` in your app's Info.plist
100    /// for microphone access permission.
101    ///
102    /// # Availability
103    /// macOS 15.0+. On earlier versions, this setting has no effect.
104    ///
105    /// # Example
106    /// ```rust,no_run
107    /// use screencapturekit::prelude::*;
108    ///
109    /// let mut config = SCStreamConfiguration::default();
110    /// config.set_captures_audio(true);       // System audio
111    /// config.set_captures_microphone(true);  // Microphone audio (macOS 15.0+)
112    /// config.set_sample_rate(48000);
113    /// config.set_channel_count(2);
114    /// ```
115    pub fn set_captures_microphone(&mut self, captures_microphone: bool) {
116        unsafe {
117            crate::ffi::sc_stream_configuration_set_captures_microphone(
118                self.as_ptr(),
119                captures_microphone,
120            );
121        }
122    }
123
124    /// Get whether microphone capture is enabled (macOS 15.0+).
125    pub fn get_captures_microphone(&self) -> bool {
126        unsafe { crate::ffi::sc_stream_configuration_get_captures_microphone(self.as_ptr()) }
127    }
128
129    /// Exclude current process audio from capture.
130    ///
131    /// When set to `true`, the stream will not capture audio from the current
132    /// process, preventing feedback loops in recording applications.
133    ///
134    /// # Example
135    /// ```rust,no_run
136    /// use screencapturekit::prelude::*;
137    ///
138    /// let mut config = SCStreamConfiguration::default();
139    /// config.set_captures_audio(true);
140    /// config.set_excludes_current_process_audio(true); // Prevent feedback
141    /// ```
142    pub fn set_excludes_current_process_audio(&mut self, excludes: bool) {
143        unsafe {
144            crate::ffi::sc_stream_configuration_set_excludes_current_process_audio(
145                self.as_ptr(),
146                excludes,
147            );
148        }
149    }
150
151    /// Get whether current process audio is excluded from capture.
152    pub fn get_excludes_current_process_audio(&self) -> bool {
153        unsafe {
154            crate::ffi::sc_stream_configuration_get_excludes_current_process_audio(self.as_ptr())
155        }
156    }
157
158    /// Set microphone capture device ID (macOS 15.0+).
159    ///
160    /// Specifies which microphone device to capture from. Use `None` for the
161    /// default system microphone.
162    ///
163    /// # Availability
164    /// macOS 15.0+. On earlier versions, this setting has no effect.
165    ///
166    /// # Example
167    /// ```rust,no_run
168    /// use screencapturekit::prelude::*;
169    ///
170    /// let mut config = SCStreamConfiguration::default();
171    /// config.set_captures_microphone(true);
172    /// config.set_microphone_capture_device_id(Some("AppleHDAEngineInput:1B,0,1,0:1"));
173    /// ```
174    pub fn set_microphone_capture_device_id(&mut self, device_id: Option<&str>) {
175        unsafe {
176            if let Some(id) = device_id {
177                if let Ok(c_id) = std::ffi::CString::new(id) {
178                    crate::ffi::sc_stream_configuration_set_microphone_capture_device_id(
179                        self.as_ptr(),
180                        c_id.as_ptr(),
181                    );
182                }
183            } else {
184                crate::ffi::sc_stream_configuration_set_microphone_capture_device_id(
185                    self.as_ptr(),
186                    std::ptr::null(),
187                );
188            }
189        }
190    }
191
192    /// Get microphone capture device ID (macOS 15.0+).
193    pub fn get_microphone_capture_device_id(&self) -> Option<String> {
194        unsafe {
195            ffi_string_from_buffer(SMALL_BUFFER_SIZE, |buf, len| {
196                crate::ffi::sc_stream_configuration_get_microphone_capture_device_id(
197                    self.as_ptr(),
198                    buf,
199                    len,
200                )
201            })
202        }
203    }
204}