{ lib, config, pkgs, ... }: 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 = { enable = mkEnableOption "enables webcam RTSP publisher"; device = mkOption { type = types.str; default = "/dev/v4l/by-id/usb-GENERAL_GENERAL_WEBCAM-video-index0"; description = "V4L2 device used as input for ffmpeg."; }; rtspUrl = mkOption { type = types.str; default = "rtsp://192.168.1.143:8554/laptop"; description = "Destination RTSP URL where ffmpeg publishes the stream."; }; framerate = mkOption { type = types.int; default = 30; description = "Input framerate for the webcam stream."; }; videoSize = mkOption { type = types.str; default = "1280x720"; description = "Input video size for the webcam stream."; }; 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; }; }