Files
harry f2eb7139da 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.
2026-10-08 14:12:06 +02:00

57 lines
2.3 KiB
Rust

//! 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();
}
}