added support for mulitple feeds

This commit is contained in:
fwastring 2026-03-29 15:11:00 +02:00
parent 57133bed53
commit 56d2144bcc
2 changed files with 85 additions and 27 deletions

View file

@ -28,11 +28,20 @@ in
webcam-rtsp = { webcam-rtsp = {
enable = true; enable = true;
# device = "/dev/v4l/by-id/usb-GENERAL_GENERAL_WEBCAM-video-index0"; streams = {
device = "/dev/v4l/by-id/usb-Generic_HD_WebCam_200901010001-video-index0"; frontcam = {
rtspUrl = "rtsp://192.168.1.143:8554/laptop"; device = "/dev/v4l/by-id/usb-Generic_HD_WebCam_200901010001-video-index0";
framerate = 30; rtspUrl = "rtsp://192.168.1.143:8554/frontcam";
videoSize = "1280x720"; 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; security.sudo.wheelNeedsPassword = false;

View file

@ -5,6 +5,24 @@
... ...
}: }:
with lib; 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 = { options = {
webcam-rtsp = { webcam-rtsp = {
@ -29,29 +47,60 @@ with lib;
default = "1280x720"; default = "1280x720";
description = "Input video size for the webcam stream."; description = "Input video size for the webcam stream.";
}; };
}; streams = mkOption {
}; type = types.attrsOf (
types.submodule {
config = mkIf config.webcam-rtsp.enable { options = {
systemd.services.webcam-rtsp-publisher = { device = mkOption {
description = "Publish USB webcam to MediaMTX over RTSP"; type = types.str;
wantedBy = [ "multi-user.target" ]; description = "V4L2 device used as input for ffmpeg.";
after = [ "network-online.target" ]; };
wants = [ "network-online.target" ]; rtspUrl = mkOption {
type = types.str;
serviceConfig = { description = "Destination RTSP URL where ffmpeg publishes the stream.";
Type = "simple"; };
Restart = "always"; framerate = mkOption {
RestartSec = "2"; type = types.int;
ExecStart = '' default = 30;
${pkgs.ffmpeg}/bin/ffmpeg \ description = "Input framerate for this stream.";
-hide_banner -loglevel warning \ };
-f v4l2 -framerate ${toString config.webcam-rtsp.framerate} -video_size ${config.webcam-rtsp.videoSize} \ videoSize = mkOption {
-i ${config.webcam-rtsp.device} \ type = types.str;
-vcodec libx264 -tune zerolatency -preset veryfast \ default = "1280x720";
-f rtsp ${config.webcam-rtsp.rtspUrl} 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;
};
} }