106 lines
3.1 KiB
Nix
106 lines
3.1 KiB
Nix
{
|
|
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;
|
|
};
|
|
}
|