record-daemon: fix linux builds
Some checks failed
record-daemon / Build, check and test (push) Failing after 55s
record-daemon / Build Windows (xwin) (push) Has been skipped

This commit is contained in:
2026-03-21 13:40:10 +01:00
parent fb3a26b961
commit 5121a46533
5 changed files with 154 additions and 20 deletions

View File

@@ -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",

View File

@@ -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]

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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 {