record-daemon: fix linux builds
This commit is contained in:
1
record-daemon/Cargo.lock
generated
1
record-daemon/Cargo.lock
generated
@@ -2988,6 +2988,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e513e435a8898a0002270f29d0a708b7879708fb5c4d00e46983ca2d2d378cf0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"libc",
|
||||
"signal-hook",
|
||||
"tokio",
|
||||
|
||||
@@ -73,7 +73,7 @@ display-info = "0.5"
|
||||
# Signal handling for graceful shutdown (Unix only)
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
signal-hook = "0.4"
|
||||
signal-hook-tokio = { version = "0.4" }
|
||||
signal-hook-tokio = { version = "0.4", features = ["futures-v0_3"] }
|
||||
|
||||
# Windows-specific dependencies
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
|
||||
@@ -501,16 +501,16 @@ async fn main() -> Result<()> {
|
||||
let mut daemon = Daemon::new(settings);
|
||||
|
||||
// Handle shutdown signals
|
||||
let _shutdown_tx = daemon.shutdown_tx.clone();
|
||||
let shutdown_tx = daemon.shutdown_tx.clone();
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use futures::StreamExt;
|
||||
use signal_hook::consts::signal::*;
|
||||
use signal_hook_tokio::Signals;
|
||||
|
||||
let mut signals = Signals::new([SIGTERM, SIGINT, SIGQUIT])?;
|
||||
|
||||
let handle = signals.handle();
|
||||
let tx = shutdown_tx.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
||||
@@ -369,11 +369,6 @@ fn is_nvenc_available() -> bool {
|
||||
|| std::path::Path::new("C:\\Windows\\System32\\nvEncMFTH265.dll").exists()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn is_nvenc_available() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if AMD AMF is available.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn is_amf_available() -> bool {
|
||||
@@ -381,11 +376,6 @@ fn is_amf_available() -> bool {
|
||||
std::path::Path::new("C:\\Windows\\System32\\amdocl64.dll").exists()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn is_amf_available() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if Intel QuickSync is available.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn is_quicksync_available() -> bool {
|
||||
@@ -393,11 +383,6 @@ fn is_quicksync_available() -> bool {
|
||||
std::path::Path::new("C:\\Windows\\System32\\mfx64.dll").exists()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn is_quicksync_available() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Get the best available encoder capability.
|
||||
pub fn best_available_encoder() -> EncoderCapability {
|
||||
let capabilities = detect_hardware_encoders();
|
||||
|
||||
@@ -495,6 +495,7 @@ impl ObsContext {
|
||||
}
|
||||
|
||||
/// Set up capture source with fallback from game capture to monitor capture.
|
||||
#[cfg(target_os = "windows")]
|
||||
fn setup_game_capture(&mut self) -> Result<()> {
|
||||
use std::io::Write;
|
||||
|
||||
@@ -519,7 +520,19 @@ impl ObsContext {
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to set up game capture source.
|
||||
/// Set up capture source on Linux using screen capture.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn setup_game_capture(&mut self) -> Result<()> {
|
||||
use std::io::Write;
|
||||
|
||||
info!("[CAPTURE] Setting up screen capture for Linux...");
|
||||
std::io::stderr().flush().ok();
|
||||
|
||||
self.setup_linux_screen_capture()
|
||||
}
|
||||
|
||||
/// Try to set up game capture source (Windows only).
|
||||
#[cfg(target_os = "windows")]
|
||||
fn try_game_capture(&mut self) -> Result<()> {
|
||||
use libobs_simple::sources::windows::{GameCaptureSourceBuilder, ObsGameCaptureMode};
|
||||
use libobs_simple::sources::ObsSourceBuilder;
|
||||
@@ -665,7 +678,8 @@ impl ObsContext {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set up monitor capture as fallback.
|
||||
/// Set up monitor capture as fallback (Windows only).
|
||||
#[cfg(target_os = "windows")]
|
||||
fn setup_monitor_capture(&mut self) -> Result<()> {
|
||||
use libobs_simple::sources::windows::MonitorCaptureSourceBuilder;
|
||||
use libobs_simple::sources::ObsSourceBuilder;
|
||||
@@ -821,6 +835,140 @@ impl ObsContext {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set up screen capture on Linux using X11 or PipeWire.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn setup_linux_screen_capture(&mut self) -> Result<()> {
|
||||
use libobs_simple::sources::linux::LinuxGeneralScreenCaptureBuilder;
|
||||
use libobs_simple::sources::ObsSourceBuilder;
|
||||
use std::io::Write;
|
||||
|
||||
info!("[LINUX_CAPTURE] Setting up Linux screen capture...");
|
||||
std::io::stderr().flush().ok();
|
||||
|
||||
let context = self.context.as_mut().ok_or_else(|| {
|
||||
error!("[LINUX_CAPTURE] OBS not initialized");
|
||||
std::io::stderr().flush().ok();
|
||||
RecordingError::ObsInitError("OBS not initialized".to_string())
|
||||
})?;
|
||||
|
||||
// Create a scene
|
||||
info!("[LINUX_CAPTURE] Creating scene 'main'...");
|
||||
std::io::stderr().flush().ok();
|
||||
let mut scene = context.scene("main", None).map_err(|e| {
|
||||
error!("[LINUX_CAPTURE] Failed to create scene: {:?}", e);
|
||||
std::io::stderr().flush().ok();
|
||||
RecordingError::StartError(format!("Failed to create scene: {:?}", e))
|
||||
})?;
|
||||
info!("[LINUX_CAPTURE] Scene created successfully");
|
||||
std::io::stderr().flush().ok();
|
||||
|
||||
// Build screen capture source using LinuxGeneralScreenCaptureBuilder
|
||||
// This automatically uses X11 or PipeWire depending on the platform
|
||||
info!("[LINUX_CAPTURE] Creating screen capture source builder...");
|
||||
std::io::stderr().flush().ok();
|
||||
|
||||
let builder_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
|
||||
LinuxGeneralScreenCaptureBuilder::new("screen_capture", context.runtime().clone())
|
||||
}));
|
||||
|
||||
let builder = match builder_result {
|
||||
Ok(Ok(b)) => {
|
||||
info!("[LINUX_CAPTURE] Screen capture builder created");
|
||||
std::io::stderr().flush().ok();
|
||||
b
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
error!(
|
||||
"[LINUX_CAPTURE] Failed to create screen capture builder: {:?}",
|
||||
e
|
||||
);
|
||||
std::io::stderr().flush().ok();
|
||||
return Err(RecordingError::StartError(format!(
|
||||
"Failed to create screen capture builder: {:?}",
|
||||
e
|
||||
))
|
||||
.into());
|
||||
}
|
||||
Err(panic_info) => {
|
||||
error!(
|
||||
"[LINUX_CAPTURE] PANIC creating screen capture builder: {:?}",
|
||||
panic_info
|
||||
);
|
||||
std::io::stderr().flush().ok();
|
||||
eprintln!(
|
||||
"[LINUX_CAPTURE] PANIC creating screen capture builder: {:?}",
|
||||
panic_info
|
||||
);
|
||||
return Err(RecordingError::StartError(
|
||||
"Panic creating screen capture builder".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
// Build the source
|
||||
let source_result =
|
||||
std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| builder.build()));
|
||||
|
||||
let source = match source_result {
|
||||
Ok(Ok(s)) => {
|
||||
info!("[LINUX_CAPTURE] Screen capture source created");
|
||||
std::io::stderr().flush().ok();
|
||||
s
|
||||
}
|
||||
Ok(Err(e)) => {
|
||||
error!(
|
||||
"[LINUX_CAPTURE] Failed to create screen capture source: {:?}",
|
||||
e
|
||||
);
|
||||
std::io::stderr().flush().ok();
|
||||
return Err(RecordingError::StartError(format!(
|
||||
"Failed to create screen capture source: {:?}",
|
||||
e
|
||||
))
|
||||
.into());
|
||||
}
|
||||
Err(panic_info) => {
|
||||
error!(
|
||||
"[LINUX_CAPTURE] PANIC creating screen capture source: {:?}",
|
||||
panic_info
|
||||
);
|
||||
std::io::stderr().flush().ok();
|
||||
eprintln!(
|
||||
"[LINUX_CAPTURE] PANIC creating screen capture source: {:?}",
|
||||
panic_info
|
||||
);
|
||||
return Err(RecordingError::StartError(
|
||||
"Panic creating screen capture source".to_string(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
};
|
||||
|
||||
// Add source to scene
|
||||
info!("[LINUX_CAPTURE] Adding source to scene...");
|
||||
std::io::stderr().flush().ok();
|
||||
scene.add_source(source).map_err(|e| {
|
||||
error!("[LINUX_CAPTURE] Failed to add source to scene: {:?}", e);
|
||||
std::io::stderr().flush().ok();
|
||||
RecordingError::StartError(format!("Failed to add source to scene: {:?}", e))
|
||||
})?;
|
||||
info!("[LINUX_CAPTURE] Source added to scene");
|
||||
std::io::stderr().flush().ok();
|
||||
|
||||
// Set the scene as active
|
||||
info!("[LINUX_CAPTURE] Setting scene as active on channel 0...");
|
||||
std::io::stderr().flush().ok();
|
||||
scene.set_to_channel(0).map_err(|e| {
|
||||
error!("[LINUX_CAPTURE] Failed to set scene: {:?}", e);
|
||||
RecordingError::StartError(format!("Failed to set scene: {:?}", e))
|
||||
})?;
|
||||
|
||||
info!("[LINUX_CAPTURE] Screen capture source configured successfully");
|
||||
std::io::stderr().flush().ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Stop recording.
|
||||
pub fn stop_recording(&mut self) -> Result<()> {
|
||||
if !self.recording {
|
||||
|
||||
Reference in New Issue
Block a user