test: lock speechbrain lengths and identity camera filter
Filter --cameras 1,5 by cam-NN identity instead of discovery index.
This commit is contained in:
@@ -34,6 +34,14 @@ class Camera:
|
||||
extra_video_devices: list[str] = field(default_factory=list)
|
||||
|
||||
|
||||
def select_cameras(cameras: list[Camera], spec: list[str]) -> list[Camera]:
|
||||
"""`--cameras 1,5` means identities cam-01 and cam-05, not discovery index."""
|
||||
if spec == ["all"]:
|
||||
return list(cameras)
|
||||
wanted = {f"cam-{int(i):02d}" for i in spec}
|
||||
return [c for c in cameras if c.identity in wanted]
|
||||
|
||||
|
||||
def _run(cmd: list[str]) -> str:
|
||||
return subprocess.run(cmd, capture_output=True, text=True, check=False).stdout
|
||||
|
||||
|
||||
@@ -11,3 +11,6 @@ dependencies = [
|
||||
"opencv-python-headless",
|
||||
"scipy",
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = ["pytest>=8"]
|
||||
|
||||
@@ -21,7 +21,7 @@ import time
|
||||
from pathlib import Path
|
||||
|
||||
from config import load_config, _load_dotenv
|
||||
from discovery import discover_cameras
|
||||
from discovery import discover_cameras, select_cameras
|
||||
from tokens import make_token
|
||||
|
||||
log = logging.getLogger("cameras.main")
|
||||
@@ -126,12 +126,10 @@ def main() -> int:
|
||||
c.audio_card if c.audio_card is not None else "-",
|
||||
c.usb_port or "-")
|
||||
|
||||
if cfg.cameras != ["all"]:
|
||||
wanted = set(int(i) - 1 for i in cfg.cameras)
|
||||
cameras = [c for c in cameras if c.index in wanted]
|
||||
if not cameras:
|
||||
log.error("no cameras match --cameras %s", args.cameras)
|
||||
return 2
|
||||
cameras = select_cameras(cameras, cfg.cameras)
|
||||
if not cameras:
|
||||
log.error("no cameras match --cameras %s", args.cameras)
|
||||
return 2
|
||||
|
||||
sup = Supervisor(cfg, cameras)
|
||||
for cam in cameras:
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT))
|
||||
@@ -0,0 +1,30 @@
|
||||
import inspect
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from audio_cleanup import AudioCleaner
|
||||
|
||||
|
||||
def test_enhance_batch_without_lengths_typeerror():
|
||||
c = AudioCleaner(mode="force")
|
||||
assert c.backend == "model"
|
||||
import torch
|
||||
|
||||
w = torch.zeros(1, 8000)
|
||||
with pytest.raises(TypeError):
|
||||
c._enhancer.enhance_batch(w)
|
||||
|
||||
|
||||
def test_process_uses_relative_lengths_one():
|
||||
src = inspect.getsource(AudioCleaner.process)
|
||||
assert "tensor([1.0])" in src
|
||||
|
||||
|
||||
def test_process_preserves_length_and_int16():
|
||||
c = AudioCleaner(mode="force")
|
||||
n = 16000
|
||||
pcm = (np.sin(2 * np.pi * 440 * np.arange(n) / 16000) * 8000).astype(np.int16)
|
||||
out = c.process(pcm)
|
||||
assert out.dtype == np.int16
|
||||
assert out.shape == pcm.shape
|
||||
@@ -0,0 +1,7 @@
|
||||
from config import _parse_cameras
|
||||
|
||||
|
||||
def test_parse_cameras_list():
|
||||
assert _parse_cameras("1,5") == ["1", "5"]
|
||||
assert _parse_cameras("all") == ["all"]
|
||||
assert _parse_cameras("1-3") == ["1", "2", "3"]
|
||||
@@ -0,0 +1,49 @@
|
||||
import re
|
||||
|
||||
from discovery import Camera, discover_cameras, select_cameras
|
||||
|
||||
CARD_RE = re.compile(r"\s*(\d+)\s+\[([A-Za-z0-9_]+)\s*\]:\s*(.*)")
|
||||
|
||||
|
||||
def test_padded_c920_card_line_matches():
|
||||
line = " 2 [C920 ]: USB-Audio - HD Pro Webcam C920"
|
||||
m = CARD_RE.match(line)
|
||||
assert m is not None
|
||||
assert int(m.group(1)) == 2
|
||||
assert m.group(2) == "C920"
|
||||
|
||||
|
||||
def test_naive_word_regex_misses_padding():
|
||||
line = " 2 [C920 ]: USB-Audio - HD Pro Webcam C920"
|
||||
assert re.match(r"\s*(\d+)\s+\[(\w+)\]:", line) is None
|
||||
|
||||
|
||||
def test_live_discover_present_cameras():
|
||||
cams = discover_cameras()
|
||||
assert len(cams) >= 1
|
||||
assert all(c.audio_card is not None for c in cams)
|
||||
assert all(c.serial for c in cams)
|
||||
assert all(re.match(r"cam-\d{2}$", c.identity) for c in cams)
|
||||
ids = [c.identity for c in cams]
|
||||
assert ids == sorted(ids)
|
||||
|
||||
|
||||
def test_select_cameras_by_identity_not_index():
|
||||
cams = [
|
||||
Camera(index=0, identity="cam-01", video_device="/dev/cam01",
|
||||
audio_card=2, serial="A"),
|
||||
Camera(index=1, identity="cam-05", video_device="/dev/cam05",
|
||||
audio_card=6, serial="B"),
|
||||
Camera(index=2, identity="cam-20", video_device="/dev/cam20",
|
||||
audio_card=21, serial="C"),
|
||||
]
|
||||
out = select_cameras(cams, ["1", "5"])
|
||||
assert [c.identity for c in out] == ["cam-01", "cam-05"]
|
||||
|
||||
|
||||
def test_select_cameras_all():
|
||||
cams = [
|
||||
Camera(index=0, identity="cam-01", video_device="/dev/cam01",
|
||||
audio_card=2, serial="A"),
|
||||
]
|
||||
assert select_cameras(cams, ["all"]) == cams
|
||||
Reference in New Issue
Block a user