diff --git a/maskiner/laptop/configuration.nix b/maskiner/laptop/configuration.nix index aac97f9..68cfa67 100644 --- a/maskiner/laptop/configuration.nix +++ b/maskiner/laptop/configuration.nix @@ -28,11 +28,20 @@ in webcam-rtsp = { enable = true; - # device = "/dev/v4l/by-id/usb-GENERAL_GENERAL_WEBCAM-video-index0"; - device = "/dev/v4l/by-id/usb-Generic_HD_WebCam_200901010001-video-index0"; - rtspUrl = "rtsp://192.168.1.143:8554/laptop"; - framerate = 30; - videoSize = "1280x720"; + streams = { + frontcam = { + device = "/dev/v4l/by-id/usb-Generic_HD_WebCam_200901010001-video-index0"; + rtspUrl = "rtsp://192.168.1.143:8554/frontcam"; + framerate = 15; + videoSize = "1280x720"; + }; + webcam = { + device = "/dev/v4l/by-id/usb-GENERAL_GENERAL_WEBCAM-video-index0"; + rtspUrl = "rtsp://192.168.1.143:8554/webcam"; + framerate = 15; + videoSize = "1280x720"; + }; + }; }; security.sudo.wheelNeedsPassword = false; diff --git a/moduler/services/webcam-rtsp/default.nix b/moduler/services/webcam-rtsp/default.nix index 96a5888..baf46ed 100644 --- a/moduler/services/webcam-rtsp/default.nix +++ b/moduler/services/webcam-rtsp/default.nix @@ -5,6 +5,24 @@ ... }: with lib; +let + cfg = config.webcam-rtsp; + + effectiveStreams = + if cfg.streams != { } then + cfg.streams + else + { + main = { + device = cfg.device; + rtspUrl = cfg.rtspUrl; + framerate = cfg.framerate; + videoSize = cfg.videoSize; + }; + }; + + sanitizeName = name: replaceStrings [ "/" " " ] [ "-" "-" ] name; +in { options = { webcam-rtsp = { @@ -29,29 +47,60 @@ with lib; default = "1280x720"; description = "Input video size for the webcam stream."; }; - }; - }; - - config = mkIf config.webcam-rtsp.enable { - systemd.services.webcam-rtsp-publisher = { - description = "Publish USB webcam to MediaMTX over RTSP"; - wantedBy = [ "multi-user.target" ]; - after = [ "network-online.target" ]; - wants = [ "network-online.target" ]; - - serviceConfig = { - Type = "simple"; - Restart = "always"; - RestartSec = "2"; - ExecStart = '' - ${pkgs.ffmpeg}/bin/ffmpeg \ - -hide_banner -loglevel warning \ - -f v4l2 -framerate ${toString config.webcam-rtsp.framerate} -video_size ${config.webcam-rtsp.videoSize} \ - -i ${config.webcam-rtsp.device} \ - -vcodec libx264 -tune zerolatency -preset veryfast \ - -f rtsp ${config.webcam-rtsp.rtspUrl} - ''; + streams = mkOption { + type = types.attrsOf ( + types.submodule { + options = { + device = mkOption { + type = types.str; + description = "V4L2 device used as input for ffmpeg."; + }; + rtspUrl = mkOption { + type = types.str; + description = "Destination RTSP URL where ffmpeg publishes the stream."; + }; + framerate = mkOption { + type = types.int; + default = 30; + description = "Input framerate for this stream."; + }; + videoSize = mkOption { + type = types.str; + default = "1280x720"; + description = "Input video size for this stream."; + }; + }; + } + ); + default = { }; + description = "Named stream definitions. One systemd service is created per stream."; }; }; }; + + config = mkIf cfg.enable { + systemd.services = mapAttrs' ( + streamName: streamCfg: + nameValuePair "webcam-rtsp-publisher-${sanitizeName streamName}" { + description = "Publish webcam stream '${streamName}' to MediaMTX over RTSP"; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + + serviceConfig = { + Type = "simple"; + Restart = "always"; + RestartSec = "2"; + ExecStart = '' + ${pkgs.ffmpeg}/bin/ffmpeg \ + -hide_banner -loglevel warning \ + -f v4l2 -framerate ${toString streamCfg.framerate} -video_size ${streamCfg.videoSize} \ + -i ${streamCfg.device} \ + -vcodec libx264 -tune zerolatency -preset veryfast \ + -f rtsp ${streamCfg.rtspUrl} + ''; + }; + } + ) effectiveStreams; + }; }