mod apps;
mod ffi;
mod mix;
mod monitor;
mod platform;
mod recorder;
pub use recorder::MeetingListener;
#[cfg(target_os = "macos")]
pub mod window {
pub use crate::platform::darwin::window::{
cg_window_owner, find_primary_window, window_bounds, window_exists,
};
}
#[derive(Debug, Clone)]
pub enum Event {
PermissionStatus {
permission: Permission,
status: PermissionGranted,
},
PermissionsGranted,
MeetingDetected { app: String },
MeetingUpdated { app: String, title: String },
MeetingEnded { app: String },
RecordingStarted { app: String },
RecordingEnded { app: String },
RecordingReady { path: std::path::PathBuf, app: String },
CaptureStatus { kind: CaptureKind, capturing: bool },
Error { message: String },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Permission {
Microphone,
ScreenCapture,
Accessibility,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PermissionGranted {
Granted,
NotRequested,
Denied,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CaptureKind {
Audio,
Video,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum DetectionKind { Started, Updated, Ended }
#[derive(Debug, Clone)]
pub(crate) struct Detection {
pub(crate) kind: DetectionKind,
pub(crate) app: String,
pub(crate) title: Option<String>,
}
#[derive(Debug, Clone)]
pub(crate) struct AudioChunk {
pub(crate) pcm: Vec<i16>,
}
pub(crate) struct Recording {
pub(crate) rx: crossbeam_channel::Receiver<AudioChunk>,
pub(crate) stop_fn: Option<Box<dyn FnOnce() + Send>>,
}
impl Drop for Recording {
fn drop(&mut self) {
if let Some(f) = self.stop_fn.take() { f(); }
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("monitor already started")]
AlreadyStarted,
#[error("platform init failed: {0}")]
PlatformInit(String),
#[error("recording failed: {0}")]
RecordingFailed(String),
#[error("macOS 14.2+ required for system audio tap (running {major}.{minor})")]
MacOSVersionTooOld { major: u32, minor: u32 },
#[error("permission denied — check Screen Recording / Microphone in System Settings")]
PermissionDenied,
#[error("{0}")]
Other(String),
}
pub type Result<T> = std::result::Result<T, Error>;