record-daemon: add game start and end metadata
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m9s

This commit is contained in:
2026-03-24 18:16:53 +01:00
parent fc7ba40b30
commit f90e549b1e
9 changed files with 1878 additions and 98 deletions

View File

@@ -434,6 +434,13 @@ impl ObsContext {
// Set up game capture source
self.setup_game_capture()?;
// Set up audio capture source
if self.audio_settings.enabled && self.audio_settings.capture_game {
info!("[START_REC] Setting up audio capture...");
self.setup_audio_capture()?;
info!("[START_REC] Audio capture set up successfully");
}
info!("[START_REC] Game capture set up, starting output...");
// Start the output - wrap in catch_unwind as this may crash in native code
@@ -494,8 +501,6 @@ impl ObsContext {
/// 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...");
self.setup_linux_screen_capture()
@@ -796,7 +801,6 @@ impl ObsContext {
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...");
@@ -921,6 +925,160 @@ impl ObsContext {
Ok(())
}
/// Set up audio capture for game audio (Windows only).
#[cfg(target_os = "windows")]
fn setup_audio_capture(&mut self) -> Result<()> {
use libobs_wrapper::data::ObsData;
use libobs_wrapper::utils::SourceInfo;
info!("[AUDIO_CAPTURE] Setting up WASAPI audio capture...");
let context = self.context.as_mut().ok_or_else(|| {
error!("[AUDIO_CAPTURE] OBS not initialized");
RecordingError::ObsInitError("OBS not initialized".to_string())
})?;
// Create audio source settings using JSON for reliable string handling
let settings_json = r#"{
"executable": "League of Legends.exe",
"title": "League of Legends (TM) Client",
"class": "RiotWindowClass",
"priority": 2
}"#;
let audio_settings_data = ObsData::from_json(settings_json, context.runtime().clone())
.map_err(|e| {
error!(
"[AUDIO_CAPTURE] Failed to create audio settings from JSON: {:?}",
e
);
RecordingError::StartError(format!(
"Failed to create audio settings from JSON: {:?}",
e
))
})?;
info!("[AUDIO_CAPTURE] Audio settings configured for League of Legends");
// Configure WASAPI process output capture for game audio
// This captures the audio output from a specific process (the game)
let source_info = SourceInfo::new(
"wasapi_process_output_capture",
"game_audio",
Some(audio_settings_data),
None,
);
info!("[AUDIO_CAPTURE] Creating WASAPI process output capture source...");
let audio_source_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
libobs_wrapper::sources::ObsSourceRef::new_from_info(
source_info,
context.runtime().clone(),
)
}));
let _audio_source = match audio_source_result {
Ok(Ok(s)) => {
info!("[AUDIO_CAPTURE] WASAPI audio source created");
s
}
Ok(Err(e)) => {
error!("[AUDIO_CAPTURE] Failed to create audio source: {:?}", e);
return Err(RecordingError::StartError(format!(
"Failed to create audio source: {:?}",
e
))
.into());
}
Err(panic_info) => {
error!(
"[AUDIO_CAPTURE] PANIC creating audio source: {:?}",
panic_info
);
eprintln!(
"[AUDIO_CAPTURE] PANIC creating audio source: {:?}",
panic_info
);
return Err(
RecordingError::StartError("Panic creating audio source".to_string()).into(),
);
}
};
info!("[AUDIO_CAPTURE] Audio source created successfully");
Ok(())
}
/// Set up audio capture for game audio (Linux only).
#[cfg(target_os = "linux")]
fn setup_audio_capture(&mut self) -> Result<()> {
use libobs_wrapper::utils::SourceInfo;
info!("[AUDIO_CAPTURE] Setting up PulseAudio capture...");
let context = self.context.as_mut().ok_or_else(|| {
error!("[AUDIO_CAPTURE] OBS not initialized");
RecordingError::ObsInitError("OBS not initialized".to_string())
})?;
// Create audio source settings
let audio_settings_data = context.data().map_err(|e| {
error!("[AUDIO_CAPTURE] Failed to create audio settings: {:?}", e);
RecordingError::StartError(format!("Failed to create audio settings: {:?}", e))
})?;
// Configure PulseAudio capture for game audio on Linux
let source_info = SourceInfo::new(
"pulse_input_capture",
"game_audio",
Some(audio_settings_data),
None,
);
info!("[AUDIO_CAPTURE] Creating PulseAudio capture source...");
let audio_source_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
libobs_wrapper::sources::ObsSourceRef::new_from_info(
source_info,
context.runtime().clone(),
)
}));
let _audio_source = match audio_source_result {
Ok(Ok(s)) => {
info!("[AUDIO_CAPTURE] PulseAudio source created");
s
}
Ok(Err(e)) => {
error!("[AUDIO_CAPTURE] Failed to create audio source: {:?}", e);
return Err(RecordingError::StartError(format!(
"Failed to create audio source: {:?}",
e
))
.into());
}
Err(panic_info) => {
error!(
"[AUDIO_CAPTURE] PANIC creating audio source: {:?}",
panic_info
);
eprintln!(
"[AUDIO_CAPTURE] PANIC creating audio source: {:?}",
panic_info
);
return Err(
RecordingError::StartError("Panic creating audio source".to_string()).into(),
);
}
};
info!("[AUDIO_CAPTURE] Audio source created successfully");
Ok(())
}
/// Stop recording.
pub fn stop_recording(&mut self) -> Result<()> {
if !self.recording {