feat: known-good CPU audio + 1080p VAAPI + KMS display wall
Working snapshot before the OpenVINO MetricGAN GPU spike: thread-capped SpeechBrain DelaySum+MetricGAN on CPU, hop 200 ms, video hold for A/V sync, Arc VAAPI H.264, headless kmssink wall. 32 tests passing. Do not treat this as a GPU audio path.
This commit is contained in:
@@ -26,10 +26,14 @@ class Config:
|
||||
room: str = "cameras"
|
||||
participant_prefix: str = "cam"
|
||||
# video
|
||||
width: int = 1280
|
||||
height: int = 720
|
||||
width: int = 640
|
||||
height: int = 360
|
||||
fps: int = 30
|
||||
min_fps: int = 5
|
||||
video_bitrate: int = 800_000
|
||||
video_codec: str = "h264"
|
||||
video_encoder: str = "vaapi" # auto|software|hardware|nvenc|vaapi
|
||||
vaapi_device: str = "/dev/dri/renderD129"
|
||||
# audio
|
||||
audio_rate: int = 16000
|
||||
audio_channels: int = 1
|
||||
@@ -46,6 +50,22 @@ class Config:
|
||||
publish_timeout_s: float = 60.0
|
||||
log_level: str = "INFO"
|
||||
cameras: list[str] = field(default_factory=lambda: ["all"])
|
||||
# headless displays (LiveKit subscribe -> GStreamer kmssink)
|
||||
display_count: int = 3
|
||||
display_identities: list[str] = field(
|
||||
default_factory=lambda: ["cam-01", "cam-02", "cam-03"])
|
||||
display_connectors: list[str] = field(default_factory=list)
|
||||
display_identity: str = "display-wall"
|
||||
display_roles: list[str] = field(
|
||||
default_factory=lambda: ["grid", "speaker", "screenshare"])
|
||||
display_speaker_camera: str = "cam-01" # cam-NN or "active"
|
||||
display_speaker_participant: str = "speaker"
|
||||
display_grid_cols: int = 5
|
||||
display_grid_rows: int = 4
|
||||
display_grid_width: int = 1920
|
||||
display_grid_height: int = 1080
|
||||
display_grid_fps: int = 30
|
||||
livekit_public_url: str = ""
|
||||
|
||||
|
||||
def _parse_cameras(spec: str) -> list[str]:
|
||||
@@ -66,6 +86,14 @@ def _parse_cameras(spec: str) -> list[str]:
|
||||
return out
|
||||
|
||||
|
||||
def _parse_list(spec: str) -> list[str]:
|
||||
"""Comma-separated names, preserving case (HDMI-A-7, cam-01)."""
|
||||
spec = (spec or "").strip()
|
||||
if not spec:
|
||||
return []
|
||||
return [p.strip() for p in spec.split(",") if p.strip()]
|
||||
|
||||
|
||||
def load_config(env_path: Optional[Path] = None) -> Config:
|
||||
_load_dotenv(Path(env_path or Path(__file__).parent / ".env"))
|
||||
|
||||
@@ -75,10 +103,14 @@ def load_config(env_path: Optional[Path] = None) -> Config:
|
||||
api_secret=os.environ.get("LIVEKIT_API_SECRET", ""),
|
||||
room=os.environ.get("LIVEKIT_ROOM", "cameras"),
|
||||
participant_prefix=os.environ.get("PARTICIPANT_PREFIX", "cam"),
|
||||
width=int(os.environ.get("VIDEO_WIDTH", "1280")),
|
||||
height=int(os.environ.get("VIDEO_HEIGHT", "720")),
|
||||
width=int(os.environ.get("VIDEO_WIDTH", "640")),
|
||||
height=int(os.environ.get("VIDEO_HEIGHT", "360")),
|
||||
fps=int(os.environ.get("VIDEO_FPS", "30")),
|
||||
min_fps=int(os.environ.get("VIDEO_MIN_FPS", "5")),
|
||||
video_bitrate=int(os.environ.get("VIDEO_BITRATE", "800000")),
|
||||
video_codec=os.environ.get("VIDEO_CODEC", "h264").lower(),
|
||||
video_encoder=os.environ.get("VIDEO_ENCODER", "vaapi").lower(),
|
||||
vaapi_device=os.environ.get("LIBVA_DRM_DEVICE", "/dev/dri/renderD129"),
|
||||
audio_rate=int(os.environ.get("AUDIO_SAMPLE_RATE", "16000")),
|
||||
audio_channels=int(os.environ.get("AUDIO_CHANNELS", "1")),
|
||||
enhance_mode=os.environ.get("ENHANCE_MODE", "auto").lower(),
|
||||
@@ -93,6 +125,23 @@ def load_config(env_path: Optional[Path] = None) -> Config:
|
||||
publish_timeout_s=float(os.environ.get("PUBLISH_TIMEOUT_S", "60")),
|
||||
log_level=os.environ.get("LOG_LEVEL", "INFO").upper(),
|
||||
cameras=_parse_cameras(os.environ.get("CAMERAS", "all")),
|
||||
display_count=int(os.environ.get("DISPLAY_COUNT", "3")),
|
||||
display_identities=_parse_list(
|
||||
os.environ.get("DISPLAY_IDENTITIES", "cam-01,cam-02,cam-03")),
|
||||
display_connectors=_parse_list(os.environ.get("DISPLAY_CONNECTORS", "")),
|
||||
display_identity=os.environ.get("DISPLAY_IDENTITY", "display-wall"),
|
||||
display_roles=_parse_list(
|
||||
os.environ.get("DISPLAY_ROLES", "grid,speaker,screenshare"))
|
||||
or ["grid", "speaker", "screenshare"],
|
||||
display_speaker_camera=os.environ.get("DISPLAY_SPEAKER_CAMERA", "cam-01"),
|
||||
display_speaker_participant=os.environ.get(
|
||||
"DISPLAY_SPEAKER_PARTICIPANT", "speaker"),
|
||||
display_grid_cols=int(os.environ.get("DISPLAY_GRID_COLS", "5")),
|
||||
display_grid_rows=int(os.environ.get("DISPLAY_GRID_ROWS", "4")),
|
||||
display_grid_width=int(os.environ.get("DISPLAY_GRID_WIDTH", "1920")),
|
||||
display_grid_height=int(os.environ.get("DISPLAY_GRID_HEIGHT", "1080")),
|
||||
display_grid_fps=int(os.environ.get("DISPLAY_GRID_FPS", "30")),
|
||||
livekit_public_url=os.environ.get("LIVEKIT_PUBLIC_URL", ""),
|
||||
)
|
||||
|
||||
if cfg.enhance_mode not in ("auto", "force", "off"):
|
||||
|
||||
Reference in New Issue
Block a user