diff --git a/Cargo.lock b/Cargo.lock index 5e62bfe..7015483 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "lesavka_client" -version = "0.22.56" +version = "0.22.57" dependencies = [ "anyhow", "async-stream", @@ -1686,7 +1686,7 @@ dependencies = [ [[package]] name = "lesavka_common" -version = "0.22.56" +version = "0.22.57" dependencies = [ "anyhow", "base64", @@ -1698,7 +1698,7 @@ dependencies = [ [[package]] name = "lesavka_server" -version = "0.22.56" +version = "0.22.57" dependencies = [ "anyhow", "base64", diff --git a/client/Cargo.toml b/client/Cargo.toml index f50de80..3651d2a 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -4,7 +4,7 @@ path = "src/main.rs" [package] name = "lesavka_client" -version = "0.22.56" +version = "0.22.57" edition = "2024" [dependencies] diff --git a/common/Cargo.toml b/common/Cargo.toml index dc37447..f23dd69 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lesavka_common" -version = "0.22.56" +version = "0.22.57" edition = "2024" build = "build.rs" diff --git a/scripts/manual/run_synthetic_rct_uvc_probe.py b/scripts/manual/run_synthetic_rct_uvc_probe.py index b8350ae..ec6a7d7 100755 --- a/scripts/manual/run_synthetic_rct_uvc_probe.py +++ b/scripts/manual/run_synthetic_rct_uvc_probe.py @@ -61,8 +61,11 @@ def parse_args() -> argparse.Namespace: ) parser.add_argument( "--media-control-path", - default=os.environ.get("LESAVKA_MEDIA_CONTROL", DEFAULT_MEDIA_CONTROL_PATH), - help=f"local live-media control file used with --pause-local-live-upstream (default: {DEFAULT_MEDIA_CONTROL_PATH})", + default=os.environ.get("LESAVKA_MEDIA_CONTROL", ""), + help=( + "local live-media control file used with --pause-local-live-upstream; " + f"default discovers LESAVKA_MEDIA_CONTROL from running Lesavka processes, then falls back to {DEFAULT_MEDIA_CONTROL_PATH}" + ), ) parser.add_argument( "--capture-before-inject", @@ -190,8 +193,59 @@ def media_control_with_camera(raw: str | None, enabled: bool) -> str: return " ".join(rendered) + "\n" +def discover_media_control_paths() -> list[pathlib.Path]: + candidates: set[pathlib.Path] = set() + proc = pathlib.Path("/proc") + if not proc.exists(): + return [] + for entry in proc.iterdir(): + if not entry.name.isdigit(): + continue + try: + environ = (entry / "environ").read_bytes() + cmdline = (entry / "cmdline").read_bytes().replace(b"\0", b" ") + except (FileNotFoundError, PermissionError, ProcessLookupError, OSError): + continue + if b"lesavka" not in cmdline and b"LESAVKA_MEDIA_CONTROL=" not in environ: + continue + for token in environ.split(b"\0"): + if token.startswith(b"LESAVKA_MEDIA_CONTROL="): + raw_path = token.split(b"=", 1)[1].decode(errors="replace") + if raw_path: + candidates.add(pathlib.Path(raw_path)) + return sorted( + candidates, + key=lambda path: ( + not path.exists(), + -path.stat().st_mtime if path.exists() else 0, + str(path), + ), + ) + + +def resolve_media_control_path(args: argparse.Namespace) -> pathlib.Path: + if args.media_control_path: + return pathlib.Path(args.media_control_path) + discovered = discover_media_control_paths() + if discovered: + if len(discovered) > 1: + print( + "multiple live Lesavka media control paths discovered; using " + f"{discovered[0]} candidates={[str(path) for path in discovered]}", + file=sys.stderr, + ) + else: + print(f"discovered live Lesavka media control path {discovered[0]}", file=sys.stderr) + return discovered[0] + print( + f"no running Lesavka media control path discovered; falling back to {DEFAULT_MEDIA_CONTROL_PATH}", + file=sys.stderr, + ) + return pathlib.Path(DEFAULT_MEDIA_CONTROL_PATH) + + def pause_local_live_upstream(args: argparse.Namespace) -> tuple[pathlib.Path, bytes | None]: - path = pathlib.Path(args.media_control_path) + path = resolve_media_control_path(args) original = path.read_bytes() if path.exists() else None raw = original.decode(errors="replace") if original is not None else None path.write_text(media_control_with_camera(raw, False)) diff --git a/server/Cargo.toml b/server/Cargo.toml index 9e5dbce..3957c03 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -16,7 +16,7 @@ bench = false [package] name = "lesavka_server" -version = "0.22.56" +version = "0.22.57" edition = "2024" autobins = false diff --git a/tests/manual/server/rct/synthetic_rct_uvc_probe_manual_contract.rs b/tests/manual/server/rct/synthetic_rct_uvc_probe_manual_contract.rs index 891df97..6b41f7d 100644 --- a/tests/manual/server/rct/synthetic_rct_uvc_probe_manual_contract.rs +++ b/tests/manual/server/rct/synthetic_rct_uvc_probe_manual_contract.rs @@ -98,6 +98,9 @@ fn synthetic_probe_keeps_bundled_network_ingress_and_rct_comparison_markers() { "paused local live camera upstream", "restored local live media control", "media_control_with_camera", + "discover_media_control_paths", + "resolve_media_control_path", + "discovered live Lesavka media control path", "max_lower_mae", "ffmpeg", "v4l2",