ostara host, kat-tv{,-ingest}, eeepc hardware profile

This commit is contained in:
kat witch 2021-08-08 02:16:25 +01:00
parent 18d5fb5c29
commit f0d241ef71
No known key found for this signature in database
GPG key ID: 1B477797DCA5EC72
10 changed files with 557 additions and 49 deletions

View file

@ -1,52 +1,74 @@
{ config, ... }:
{ config, lib, ... }:
with lib;
{
services.nginx.virtualHosts = {
"beltane.net.kittywit.ch" = {
useACMEHost = "beltane.net.kittywit.ch";
forceSSL = true;
locations = {
"/jellyfin/".proxyPass = "http://127.0.0.1:8096/jellyfin/";
"/jellyfin/socket" = {
proxyPass = "http://127.0.0.1:8096/jellyfin/";
extraConfig = ''
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
"/tvheadend/".proxyPass = "http://192.168.1.245:9981";
"/" = {
root = "/mnt/zraw/media/";
extraConfig = "autoindex on;";
};
"/transmission" = {
proxyPass = "http://[::1]:9091";
extraConfig = "proxy_pass_header X-Transmission-Session-Id;";
services.nginx = {
virtualHosts = {
"beltane.net.kittywit.ch" = {
useACMEHost = "beltane.net.kittywit.ch";
forceSSL = true;
locations = {
"/jellyfin/".proxyPass = "http://127.0.0.1:8096/jellyfin/";
"/jellyfin/socket" = {
proxyPass = "http://127.0.0.1:8096/jellyfin/";
extraConfig = ''
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
"/tvheadend/".proxyPass = "http://127.0.0.1:9981";
"/" = {
root = "/mnt/zraw/media/";
extraConfig = "autoindex on;";
};
"/transmission" = {
proxyPass = "http://[::1]:9091";
extraConfig = "proxy_pass_header X-Transmission-Session-Id;";
};
};
};
};
"192.168.1.223" = {
locations = {
"/jellyfin/".proxyPass = "http://127.0.0.1:8096/jellyfin/";
"/jellyfin/socket" = {
proxyPass = "http://127.0.0.1:8096/jellyfin/";
extraConfig = ''
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
"192.168.1.223" = {
locations = {
"/jellyfin/".proxyPass = "http://127.0.0.1:8096/jellyfin/";
"/jellyfin/socket" = {
proxyPass = "http://127.0.0.1:8096/jellyfin/";
extraConfig = ''
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
"/share/" = {
"/share/" = {
alias = "/mnt/zraw/media/";
extraConfig = "autoindex on;";
};
};
};
"100.103.111.44" = {
locations."/share/" = {
alias = "/mnt/zraw/media/";
extraConfig = "autoindex on;";
};
};
};
"100.103.111.44" = {
locations."/share/" = {
alias = "/mnt/zraw/media/";
extraConfig = "autoindex on;";
};
};
appendConfig = ''
rtmp {
server {
listen [::]:1935 ipv6only=off;
application stream {
live on;
allow publish all;
allow play all;
}
}
}
'';
};
kw.fw = {
private.tcp.ports = singleton 1935;
public.tcp.ports = singleton 1935;
};
}

View file

@ -0,0 +1,61 @@
{ lib, config, users, pkgs, profiles, services, ... }:
with lib;
{
# Imports
imports = [
profiles.hardware.eeepc-1015pem
profiles.laptop
services.kattv
];
# File Systems and Swap
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/469a684b-eb8f-48a8-8f98-be58528312c4";
fsType = "ext4";
};
};
swapDevices = [{ device = "/dev/disk/by-uuid/2223e305-79c9-45b3-90d7-560dcc45775a"; }];
# Bootloader
boot.loader.grub = {
enable = true;
version = 2;
device = "/dev/sda";
};
# Hardware
services.logind.lidSwitchExternalPower = "ignore";
# Networking
networking = {
hostId = "9f89b327";
useDHCP = false;
wireless.interfaces = [ "wlp2s0" ];
interfaces = {
enp1s0.useDHCP = true;
wlp2s0.useDHCP = true;
};
};
# Firewall
kw.fw = {
public = {
interfaces = singleton "wlp2s0";
tcp.ports = [ 9981 9982 ];
};
};
# State
system.stateVersion = "20.09";
}

View file

@ -14,9 +14,10 @@ with lib;
amdgpu = mkEnableOption "AMD GPU";
hcloud-imperative = mkEnableOption "Imperative Hetzner Cloud Setup";
intel = mkEnableOption "Intel CPU";
ryzen = mkEnableOption "AMD Ryzen CPU";
ms-7b86 = mkEnableOption "MSI B450-A Pro Max";
rm-310 = mkEnableOption "Intel DQ67OW";
ryzen = mkEnableOption "AMD Ryzen CPU";
eeepc-1015pem = mkEnableOption "Asus Eee PC 1015PEM";
v330-14arr = mkEnableOption "Lenovo Ideapad v330-14ARR";
};
};
@ -34,9 +35,10 @@ with lib;
amdgpu = mkEnableOption "AMD GPU";
hcloud-imperative = mkEnableOption "Imperative Hetzner Cloud Setup";
intel = mkEnableOption "Intel CPU";
ryzen = mkEnableOption "AMD Ryzen CPU";
ms-7b86 = mkEnableOption "MSI B450-A Pro Max";
rm-310 = mkEnableOption "Intel DQ67OW";
ryzen = mkEnableOption "AMD Ryzen CPU";
eeepc-1015pem = mkEnableOption "Asus Eee PC 1015PEM";
v330-14arr = mkEnableOption "Lenovo Ideapad v330-14ARR";
};
};

View file

@ -9,6 +9,12 @@ let profiles = with profiles; lib.modList {
amdgpu
];
};
rm-310 = {
imports = [
rm-310-base
intel
];
};
v330-14arr = {
imports = [
v330-14arr-base
@ -16,11 +22,11 @@ let profiles = with profiles; lib.modList {
amdgpu
];
};
rm-310 = {
eeepc-1015pem = {
imports = [
rm-310-base
intel
];
};
}; in profiles;
eeepc-1015pem-base
intel
];
};
}; in profiles;
in { __functor = self: hardwareProfiles; isModule = false; }

View file

@ -0,0 +1,17 @@
{ config, ... }:
{
deploy.profile.hardware.eeepc-1015pem = true;
boot = {
initrd = {
availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "sd_mod" ];
kernelModules = [ ];
};
kernelModules = [ ];
extraModulePackages = [ ];
kernelParams = [
"usbcore.autosuspend=-1"
];
};
}

View file

@ -0,0 +1,28 @@
{ config, pkgs, lib , ... }:
with lib;
{
kw.fw.public.tcp.ports = [ 4953 1935 ];
systemd.sockets.kattv = {
listenStreams = [ "0.0.0.0:4953" ];
socketConfig = {
Accept = true;
Backlog = 0;
MaxConnections = 1;
};
};
systemd.services."kattv@" = {
environment = pkgs.kat-tv-ingest.env;
script = "exec ${pkgs.gst_all_1.gstreamer.dev}/bin/gst-launch-1.0 -e --no-position ${pkgs.lib.gst.pipelineShellString pkgs.kat-tv-ingest.pipeline}";
wantedBy = [ "multi-user.target" ];
after = [ "nginx.service" ];
description = "RTMP stream of kat cam";
serviceConfig = {
Restart = "on-failure";
RestartSec = "10s";
};
};
}

View file

@ -0,0 +1,21 @@
{ config, pkgs, lib, ... }:
{
services.udev.extraRules = ''
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTR{index}=="0", ATTRS{idVendor}=="045e", ATTRS{idProduct}=="0779", SYMLINK+="videomew", TAG+="systemd"
'';
systemd.services.kattv = {
wantedBy = [ "dev-videomew.device" "multi-user.target" ];
after = [ "dev-videomew.device" "nginx.service" ];
description = "RTMP stream of kat cam";
bindsTo = [ "dev-videomew.device" ];
environment = pkgs.kat-tv.env;
script = "exec ${pkgs.gst_all_1.gstreamer.dev}/bin/gst-launch-1.0 -e --no-position ${pkgs.lib.gst.pipelineShellString pkgs.kat-tv.pipeline}";
serviceConfig = {
Restart = "on-failure";
RestartSec = "10s";
};
};
}

View file

@ -72,13 +72,17 @@ let
konawall = super.konawall.overide { swaySupport = true; };
wezterm-terminfo = self.callPackage ./wezterm-terminfo { inherit (self) ncurses; };
imv = super.imv.override {
withBackends = [ "freeimage" "libjpeg" "libpng" "librsvg" "libnsgif" "libheif" "libtiff" ];
};
kat-glauca-dns = self.callPackage ./kat-glauca-dns { };
wezterm-terminfo = self.callPackage ./wezterm-terminfo { inherit (self) ncurses; };
kat-tv = import ./kat-tv { pkgs = self; lib = self.lib; };
kat-tv-ingest = import ./kat-tv-ingest { pkgs = self; lib = self.lib; };
kat-website = self.callPackage ./kat-website { };
@ -102,6 +106,9 @@ let
];
config = {
allowUnfree = true;
permittedInsecurePackages = [
"ffmpeg-3.4.8"
];
};
};
in pkgs

View file

@ -0,0 +1,178 @@
{ pkgs ? import <nixpkgs> { }, lib }: with lib; with pkgs.gst_all_1; let
queue_frame = {
element."queue" = {
leaky = "downstream";
flush-on-eos = true;
max-size-buffers = 3;
};
};
queue_data = {
element.queue = {
leaky = "downstream";
};
};
videoconvert_cpu = {
element.videoconvert = {
n-threads = 4;
dither = 0;
chroma-resampler = 0;
chroma-mode = 3;
};
};
videoconvert_gpu = [
# TODO: vulkancolorconvert?
"glupload"
"glcolorconvert"
"gldownload"
];
cameracapture = {
element."v4l2src" = {
device = "/dev/videomew";
saturation = 100;
brightness = 100;
extra-controls = "c,exposure_auto=3";
};
};
v4l2src = [
cameracapture
{
caps."image/jpeg" = {
width = 1280;
height = 720;
framerate = "30/1"; # "10/1"
};
}
"jpegdec"
queue_frame
];
filesrc = [
{
element.filesrc = {
location = "rawvid.mkv";
};
}
"matroskademux"
];
denoise = {
element.frei0r-filter-hqdn3d = {
spatial = 0.175; #0.325;
temporal = 0.06; #0.11;
};
};
encodeopts = {
speed-preset = "ultrafast";
tune = "zerolatency";
pass = "qual";
#psy-tune = "film";
#noise-reduction=0;
quantizer = 27;
bitrate = 8192;
rc-lookahead = 6;
};
encode_intra = [
{
element.x264enc = {
intra-refresh = true;
key-int-max = 0;
} // encodeopts;
}
{
caps."video/x-h264" = {
profile = "high-4:2:2-intra";
};
}
"h264parse"
];
encode_high = [
{
element.x264enc = {
key-int-max = 150;
} // encodeopts;
}
{
caps."video/x-h264" = {
profile = "high";
};
}
"h264parse"
];
rtmpsink = [
queue_data
"flvmux"
{
element.rtmp2sink = {
location = "rtmp://localhost:1935/stream/kattv";
};
}
];
filesink = [
"matroskamux"
{
element.filesink = {
location = "out.mkv";
};
}
];
videosink = "autovideosink";
pipeline = [
#filesrc
#v4l2src
{
element.fdsrc = {
fd = 3;
};
}
"matroskademux"
"jpegdec"
queue_frame
videoconvert_cpu
denoise
videoconvert_cpu
encode_high
rtmpsink
#filesink
];
#gst-launch-1.0 $camera ! $videoconvert ! $queue ! $denoise ! $encode ! $outfile
env = {
FREI0R_PATH = "${pkgs.frei0r}/lib/frei0r-1";
GST_PLUGIN_SYSTEM_PATH_1_0 = with pkgs.gst_all_1; lib.makeSearchPath "lib/gstreamer-1.0" [
gstreamer
gst-plugins-base
gst-plugins-good
gst-plugins-bad
gst-plugins-ugly
];
};
shell = pkgs.mkShell (env // {
nativeBuildInputs = [ gstreamer kattv ];
});
in
{
inherit shell pipeline env;
}
#!/usr/bin/env bash
/*
#encode='x264enc intra-refresh=true key-int-max=0 speed-preset=superfast tune=zerolatency pass=qual psy-tune=film noise-reduction=250 quantizer=23 rc-lookahead=15 ! video/x-h264,profile=high-4:2:2-intra ! h264parse'
#encode="x264enc intra-refresh=true key-int-max=0 $encodeopts ! video/x-h264,profile=high-4:2:2-intra ! h264parse ! $bufqueue"
encode="x264enc key-int-max=50 $encodeopts ! video/x-h264,profile=high-4:2:2 ! h264parse ! $bufqueue"
# original pipeline:
# gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw,format=YUY2,width=1280,height=800,framerate=10/1" ! videoconvert ! x264enc intra-refresh=true key-int-max=0 speed-preset=superfast tune=zerolatency pass=qual psy-tune=film noise-reduction=250 quantizer=23 rc-lookahead=15 ! video/x-h264,profile=high-4:2:2-intra ! h264parse ! flvmux ! rtmpsink location="rtmp://kittywit.ch/kattv/meowlymeowl live=1"
#gst-launch-1.0 filesrc location=rawvid.mkv ! mkvdemux ! "video/x-raw,format=YUY2,width=1280,height=800,framerate=10/1" ! videoconvert ! x264enc intra-refresh=true key-int-max=0 speed-preset=superfast tune=zerolatency pass=qual psy-tune=film noise-reduction=250 quantizer=23 rc-lookahead=15 ! video/x-h264,profile=high-4:2:2-intra ! h264parse ! flvmux ! filesink location=out.flv
#gst-launch-1.0 filesrc location=rawvid.mkv ! matroskademux ! "video/x-raw,format=YUY2,width=1280,height=800,framerate=10/1" ! videoconvert ! "video/x-raw,format=RGBA" ! frei0r-filter-hqdn3d spatial=0.35 temporal=0.115 ! videoconvert ! autovideosink
outfile='flvmux ! filesink location=out.flv'
#gst-launch-1.0 $camera ! $videoconvert ! $denoise ! autovideosink
gst-launch-1.0 $camera ! $videoconvert ! $queue ! $denoise ! $encode ! $outfile
#gst-launch-1.0 $camera ! $videoconvert ! $encode ! $outfile
*/

166
pkgs/kat-tv/default.nix Normal file
View file

@ -0,0 +1,166 @@
{ pkgs ? import <nixpkgs> { }, lib }: with lib; with pkgs.gst_all_1; let
queue_frame = {
element."queue" = {
leaky = "downstream";
flush-on-eos = true;
max-size-buffers = 3;
};
};
queue_data = {
element.queue = {
leaky = "downstream";
};
};
videoconvert_cpu = {
element.videoconvert = {
n-threads = 4;
dither = 0;
chroma-resampler = 0;
chroma-mode = 3;
};
};
videoconvert_gpu = [
# TODO: vulkancolorconvert?
"glupload"
"glcolorconvert"
"gldownload"
];
cameracapture = {
element."v4l2src" = {
device = "/dev/videomew";
saturation = 100;
brightness = 100;
extra-controls = "c,exposure_auto=3";
};
};
v4l2src = [
cameracapture
{
caps."image/jpeg" = {
width = 1280;
height = 720;
framerate = "30/1"; # "10/1"
};
}
];
filesrc = [
{
element.filesrc = {
location = "rawvid.mkv";
};
}
"matroskademux"
];
denoise = {
element.frei0r-filter-hqdn3d = {
spatial = 0.175; #0.325;
temporal = 0.06; #0.11;
};
};
encodeopts = {
speed-preset = "ultrafast";
tune = "zerolatency";
pass = "qual";
#psy-tune = "film";
#noise-reduction=0;
quantizer = 27;
bitrate = 8192;
rc-lookahead = 6;
};
encode_intra = [
{
element.x264enc = {
intra-refresh = true;
key-int-max = 0;
} // encodeopts;
}
{
caps."video/x-h264" = {
profile = "high-4:2:2-intra";
};
}
"h264parse"
];
encode_high = [
{
element.x264enc = {
key-int-max = 150;
} // encodeopts;
}
{
caps."video/x-h264" = {
profile = "high";
};
}
"h264parse"
];
rtmpsink = [
queue_data
"flvmux"
{
element.rtmp2sink = {
location = "rtmp://192.168.1.223:1935/stream/kattv";
};
}
];
filesink = [
"matroskamux"
{
element.filesink = {
location = "out.mkv";
};
}
];
videosink = "autovideosink";
pipeline = v4l2src ++ [
#filesrc
{ element.matroskamux.streamable = true; }
{
element.tcpclientsink = {
host = "192.168.1.223";
port = "4953";
sync = false;
};
}
];
#gst-launch-1.0 $camera ! $videoconvert ! $queue ! $denoise ! $encode ! $outfile
env = {
FREI0R_PATH = "${pkgs.frei0r}/lib/frei0r-1";
GST_PLUGIN_SYSTEM_PATH_1_0 = with pkgs.gst_all_1; lib.makeSearchPath "lib/gstreamer-1.0" [
gstreamer
gst-plugins-base
gst-plugins-good
gst-plugins-bad
gst-plugins-ugly
];
};
shell = pkgs.mkShell (env // {
nativeBuildInputs = [ gstreamer kattv ];
});
in
{
inherit shell pipeline env;
}
#!/usr/bin/env bash
/*
#encode='x264enc intra-refresh=true key-int-max=0 speed-preset=superfast tune=zerolatency pass=qual psy-tune=film noise-reduction=250 quantizer=23 rc-lookahead=15 ! video/x-h264,profile=high-4:2:2-intra ! h264parse'
#encode="x264enc intra-refresh=true key-int-max=0 $encodeopts ! video/x-h264,profile=high-4:2:2-intra ! h264parse ! $bufqueue"
encode="x264enc key-int-max=50 $encodeopts ! video/x-h264,profile=high-4:2:2 ! h264parse ! $bufqueue"
# original pipeline:
# gst-launch-1.0 v4l2src device=/dev/video0 ! "video/x-raw,format=YUY2,width=1280,height=800,framerate=10/1" ! videoconvert ! x264enc intra-refresh=true key-int-max=0 speed-preset=superfast tune=zerolatency pass=qual psy-tune=film noise-reduction=250 quantizer=23 rc-lookahead=15 ! video/x-h264,profile=high-4:2:2-intra ! h264parse ! flvmux ! rtmpsink location="rtmp://kittywit.ch/kattv/meowlymeowl live=1"
#gst-launch-1.0 filesrc location=rawvid.mkv ! mkvdemux ! "video/x-raw,format=YUY2,width=1280,height=800,framerate=10/1" ! videoconvert ! x264enc intra-refresh=true key-int-max=0 speed-preset=superfast tune=zerolatency pass=qual psy-tune=film noise-reduction=250 quantizer=23 rc-lookahead=15 ! video/x-h264,profile=high-4:2:2-intra ! h264parse ! flvmux ! filesink location=out.flv
#gst-launch-1.0 filesrc location=rawvid.mkv ! matroskademux ! "video/x-raw,format=YUY2,width=1280,height=800,framerate=10/1" ! videoconvert ! "video/x-raw,format=RGBA" ! frei0r-filter-hqdn3d spatial=0.35 temporal=0.115 ! videoconvert ! autovideosink
outfile='flvmux ! filesink location=out.flv'
#gst-launch-1.0 $camera ! $videoconvert ! $denoise ! autovideosink
gst-launch-1.0 $camera ! $videoconvert ! $queue ! $denoise ! $encode ! $outfile
#gst-launch-1.0 $camera ! $videoconvert ! $encode ! $outfile
*/