Skip to content

Commit

Permalink
Support ScreenCapture loopback
Browse files Browse the repository at this point in the history
  • Loading branch information
Kree0 authored and Kree0 committed Nov 17, 2024
1 parent 582e93c commit e851e41
Show file tree
Hide file tree
Showing 5 changed files with 456 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mach2 = "0.4" # For access to mach_timebase type.

[target.'cfg(target_os = "macos")'.dependencies]
coreaudio-rs = { version = "0.11", default-features = false, features = ["audio_unit", "core_audio"] }
cidre = { git = "https://github.com/yury/cidre.git", rev = "f05c428" }

[target.'cfg(target_os = "ios")'.dependencies]
coreaudio-rs = { version = "0.11", default-features = false, features = ["audio_unit", "core_audio", "audio_toolbox"] }
Expand Down
2 changes: 2 additions & 0 deletions src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub(crate) mod jack;
pub(crate) mod null;
#[cfg(target_os = "android")]
pub(crate) mod oboe;
#[cfg(target_os = "macos")]
pub(crate) mod screencapturekit;
#[cfg(windows)]
pub(crate) mod wasapi;
#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
Expand Down
60 changes: 60 additions & 0 deletions src/host/screencapturekit/enumerate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use std::vec::IntoIter as VecIntoIter;

use cidre::sc;

use crate::{BackendSpecificError, DevicesError, SupportedStreamConfigRange};

use super::Device;

pub struct Devices(VecIntoIter<Device>);

impl Devices {
pub fn new() -> Result<Self, DevicesError> {
let (tx, rx) = std::sync::mpsc::channel();
sc::ShareableContent::current_with_ch(move |sc, e| {
let res = if let Some(err) = e {
Result::Err(BackendSpecificError {
description: format!("{err}"),
})
} else if let Some(sc) = sc {
Result::Ok(sc.retained())
} else {
Result::Err(BackendSpecificError {
description: "Failed to get current shareable content".to_string(),
})
};
tx.send(res).unwrap();
});
let sc_shareable_content = rx.recv().unwrap()?;

let mut res = Vec::new();
for display in sc_shareable_content.displays().iter() {
res.push(Device::new(display.retained()));
}

Ok(Devices(res.into_iter()))
}
}

unsafe impl Send for Devices {}
unsafe impl Sync for Devices {}

impl Iterator for Devices {
type Item = Device;

fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}

pub fn default_input_device() -> Option<Device> {
let devices = Devices::new().ok()?;
devices.into_iter().next()
}

pub fn default_output_device() -> Option<Device> {
None
}

pub type SupportedInputConfigs = VecIntoIter<SupportedStreamConfigRange>;
pub type SupportedOutputConfigs = VecIntoIter<SupportedStreamConfigRange>;
Loading

1 comment on commit e851e41

@rustdesk
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest getting rid of expect.

Please sign in to comment.