feat: add OBS recording engine and validation probe
clipbin-obs starts the pinned libobs on a dedicated thread, opens exactly the bundled plugin allowlist, and records official capture sources through one hardware encoder into keyframe-aligned Matroska segments. Status reaches Recording only once the source has a picture and the segment grows on disk. clipbin-probe lists and verifies hardware encoders and records from a real capture source, printing status, health and segment events for validation.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
//! Makes development builds run against the OBS runtime in target/obs-runtime.
|
||||
//!
|
||||
//! OBS starts `obs-ffmpeg-mux` from the running executable's directory, and on
|
||||
//! Windows the OBS DLLs must sit beside the executable too, so they are linked
|
||||
//! (Unix) or copied (Windows) into the Cargo profile directory. A symlink keeps
|
||||
//! the helper's `$ORIGIN/../lib` runpath pointing into the runtime. Packaged
|
||||
//! builds place the executable in the runtime's own bin directory instead (see
|
||||
//! clipbin_obs::RuntimeLayout).
|
||||
use std::{env, fs, path::PathBuf};
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-env-changed=CLIPBIN_OBS_RUNTIME_DIR");
|
||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
if target_os == "linux" {
|
||||
// Packaged layout: <root>/bin/<exe> loads <root>/lib/libobs.so.
|
||||
println!("cargo:rustc-link-arg-bins=-Wl,-rpath,$ORIGIN/../lib");
|
||||
}
|
||||
|
||||
let Some(runtime_dir) = env::var_os("CLIPBIN_OBS_RUNTIME_DIR") else {
|
||||
return;
|
||||
};
|
||||
let runtime = PathBuf::from(runtime_dir).join(format!("{target_os}-{arch}"));
|
||||
// OUT_DIR is <profile>/build/<package>-<hash>/out.
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let profile_dir = out_dir.ancestors().nth(3).unwrap().to_path_buf();
|
||||
|
||||
let (bin_dir, lib_dir) = match target_os.as_str() {
|
||||
"windows" => (runtime.join("bin").join("64bit"), None),
|
||||
_ => (runtime.join("bin"), Some(runtime.join("lib"))),
|
||||
};
|
||||
if let Some(lib_dir) = lib_dir {
|
||||
println!("cargo:rustc-link-arg-bins=-Wl,-rpath,{}", lib_dir.display());
|
||||
}
|
||||
let Ok(entries) = fs::read_dir(&bin_dir) else {
|
||||
println!(
|
||||
"cargo:warning=OBS runtime not found at {}; run scripts/obs/ to assemble it",
|
||||
runtime.display()
|
||||
);
|
||||
return;
|
||||
};
|
||||
println!("cargo:rerun-if-changed={}", bin_dir.display());
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
if !path.is_file() {
|
||||
continue;
|
||||
}
|
||||
let destination = profile_dir.join(entry.file_name());
|
||||
let _ = fs::remove_file(&destination);
|
||||
#[cfg(unix)]
|
||||
std::os::unix::fs::symlink(&path, &destination).unwrap();
|
||||
#[cfg(not(unix))]
|
||||
fs::copy(&path, &destination).unwrap();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user