feat: macos, audio, loopback (#10025)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -837,7 +837,7 @@ async fn check_software_update_() -> hbb_common::ResultType<()> {
|
||||
let _ = crate::flutter::push_global_event(crate::flutter::APP_TYPE_MAIN, data);
|
||||
}
|
||||
}
|
||||
*SOFTWARE_UPDATE_URL.lock().unwrap() = response_url;
|
||||
*SOFTWARE_UPDATE_URL.lock().unwrap() = response_url;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -774,13 +774,6 @@ pub fn main_get_sound_inputs() -> Vec<String> {
|
||||
vec![String::from("")]
|
||||
}
|
||||
|
||||
pub fn main_get_default_sound_input() -> Option<String> {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
return get_default_sound_input();
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
None
|
||||
}
|
||||
|
||||
pub fn main_get_login_device_info() -> SyncReturn<String> {
|
||||
SyncReturn(get_login_device_info_json())
|
||||
}
|
||||
@@ -2317,6 +2310,16 @@ pub fn session_request_new_display_init_msgs(session_id: SessionID, display: usi
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main_audio_support_loopback() -> SyncReturn<bool> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let is_surpport = true;
|
||||
#[cfg(feature = "screencapturekit")]
|
||||
let is_surpport = crate::audio_service::is_screen_capture_kit_available();
|
||||
#[cfg(not(any(target_os = "windows", feature = "screencapturekit")))]
|
||||
let is_surpport = false;
|
||||
SyncReturn(is_surpport)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod server_side {
|
||||
use hbb_common::{config, log};
|
||||
|
||||
@@ -156,6 +156,14 @@ mod pa_impl {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(feature = "screencapturekit")]
|
||||
pub fn is_screen_capture_kit_available() -> bool {
|
||||
cpal::available_hosts()
|
||||
.iter()
|
||||
.any(|host| *host == cpal::HostId::ScreenCaptureKit)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
mod cpal_impl {
|
||||
use self::service::{Reset, ServiceSwap};
|
||||
@@ -170,6 +178,11 @@ mod cpal_impl {
|
||||
static ref INPUT_BUFFER: Arc<Mutex<std::collections::VecDeque<f32>>> = Default::default();
|
||||
}
|
||||
|
||||
#[cfg(feature = "screencapturekit")]
|
||||
lazy_static::lazy_static! {
|
||||
static ref HOST_SCREEN_CAPTURE_KIT: Result<Host, cpal::HostUnavailable> = cpal::host_from_id(cpal::HostId::ScreenCaptureKit);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct State {
|
||||
stream: Option<(Box<dyn StreamTrait>, Arc<Message>)>,
|
||||
@@ -246,6 +259,27 @@ mod cpal_impl {
|
||||
send_f32(&data, encoder, sp);
|
||||
}
|
||||
|
||||
#[cfg(feature = "screencapturekit")]
|
||||
fn get_device() -> ResultType<(Device, SupportedStreamConfig)> {
|
||||
let audio_input = super::get_audio_input();
|
||||
if !audio_input.is_empty() {
|
||||
return get_audio_input(&audio_input);
|
||||
}
|
||||
if !is_screen_capture_kit_available() {
|
||||
return get_audio_input("");
|
||||
}
|
||||
let device = HOST_SCREEN_CAPTURE_KIT
|
||||
.as_ref()?
|
||||
.default_input_device()
|
||||
.with_context(|| "Failed to get default input device for loopback")?;
|
||||
let format = device
|
||||
.default_input_config()
|
||||
.map_err(|e| anyhow!(e))
|
||||
.with_context(|| "Failed to get input output format")?;
|
||||
log::info!("Default input format: {:?}", format);
|
||||
Ok((device, format))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_device() -> ResultType<(Device, SupportedStreamConfig)> {
|
||||
let audio_input = super::get_audio_input();
|
||||
@@ -267,7 +301,7 @@ mod cpal_impl {
|
||||
Ok((device, format))
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[cfg(not(any(windows, feature = "screencapturekit")))]
|
||||
fn get_device() -> ResultType<(Device, SupportedStreamConfig)> {
|
||||
let audio_input = super::get_audio_input();
|
||||
get_audio_input(&audio_input)
|
||||
@@ -275,7 +309,20 @@ mod cpal_impl {
|
||||
|
||||
fn get_audio_input(audio_input: &str) -> ResultType<(Device, SupportedStreamConfig)> {
|
||||
let mut device = None;
|
||||
if !audio_input.is_empty() {
|
||||
#[cfg(feature = "screencapturekit")]
|
||||
if !audio_input.is_empty() && is_screen_capture_kit_available() {
|
||||
for d in HOST_SCREEN_CAPTURE_KIT
|
||||
.as_ref()?
|
||||
.devices()
|
||||
.with_context(|| "Failed to get audio devices")?
|
||||
{
|
||||
if d.name().unwrap_or("".to_owned()) == audio_input {
|
||||
device = Some(d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if device.is_none() && !audio_input.is_empty() {
|
||||
for d in HOST
|
||||
.devices()
|
||||
.with_context(|| "Failed to get audio devices")?
|
||||
|
||||
@@ -321,6 +321,8 @@ pub fn get_sound_inputs() -> Vec<String> {
|
||||
fn get_sound_inputs_() -> Vec<String> {
|
||||
let mut out = Vec::new();
|
||||
use cpal::traits::{DeviceTrait, HostTrait};
|
||||
// Do not use `cpal::host_from_id(cpal::HostId::ScreenCaptureKit)` for feature = "screencapturekit"
|
||||
// Because we explicitly handle the "System Sound" device.
|
||||
let host = cpal::default_host();
|
||||
if let Ok(devices) = host.devices() {
|
||||
for device in devices {
|
||||
|
||||
Reference in New Issue
Block a user