1
0
mirror of https://github.com/kmein/niveum synced 2026-03-20 20:01:08 +01:00

feat(radio): add index html

This commit is contained in:
2021-06-08 22:04:17 +02:00
parent d480eff8cd
commit 70414128e5
4 changed files with 135 additions and 113 deletions

View File

@@ -4,9 +4,31 @@ let
radioStore = "/var/lib/radio"; radioStore = "/var/lib/radio";
htgenPort = 8080; htgenPort = 8080;
meddl = { streamPort = 8000; mpdPort = 6600; }; stations = {
lyrikline = { streamPort = 8001; mpdPort = 6601; }; meddl = {
lyrik = { streamPort = 8002; mpdPort = 6602; }; streamPort = 8000;
mpdPort = 6600;
description = ''
Drachenlord-Radio. Kopie von <a href="https://antenne-asb.ga/">Hit Radio Antenne ASB</a>, dem Anti-Mobbing-Sender.
<em>Hier wird nicht nur, aber auch Meddl gespielt.
Für dich On Air einer unserer Top Moderatoren Rainer Winkler. Als einer der größten Meddler aller Zeiten, hat er sich schon in seiner Kinheit einen Namen gemacht. Auch wenn er dem Meddl zugeneigt ist und HipHop-Kaschber eigentlich hasst, spielt er mittlerweile gelegentlich auch Techno oder HipHop.</em>
'';
};
lyrikline = {
streamPort = 8001;
mpdPort = 6601;
description = ''
Weltklang. Welt als ewiges Gedicht, das seine Schallspuren durch Raum und Zeit jagt. Endlose Zufallswiedergabe von <a href="//lyrikline.org">lyrikline</a>. Listen to the sound of voices and poems permeating linguistic and geographic barriers, 24 hours per day.
'';
};
lyrik = {
streamPort = 8002;
mpdPort = 6602;
description = ''
Deutsche Lyrik, die du noch nicht gut genug kennst. Tritt in einen Fluss aus Reim und Maß; keine zwei Mal ist er derselbe.
'';
};
};
mpd-add-with-tags = pkgs.writers.writeHaskell "mpd-add-with-tags" { mpd-add-with-tags = pkgs.writers.writeHaskell "mpd-add-with-tags" {
libraries = with pkgs.haskellPackages; [ optparse-generic libmpd ]; libraries = with pkgs.haskellPackages; [ optparse-generic libmpd ];
} '' } ''
@@ -30,9 +52,9 @@ let
maybe (pure ()) (addTagId songId Title . fromString) $ title options maybe (pure ()) (addTagId songId Title . fromString) $ title options
''; '';
mpc-lyrikline = pkgs.writers.writeDashBin "mpc-lyrikline" ''MPD_PORT=${toString lyrikline.mpdPort} ${pkgs.mpc_cli}/bin/mpc "$@"''; mpcs = lib.mapAttrs (name: station: pkgs.writers.writeDashBin "mpc-${name}" ''
mpc-meddl = pkgs.writers.writeDashBin "mpc-meddl" ''MPD_PORT=${toString meddl.mpdPort} ${pkgs.mpc_cli}/bin/mpc "$@"''; MPD_PORT=${toString station.mpdPort} ${pkgs.mpc_cli}/bin/mpc "$@"
mpc-lyrik = pkgs.writers.writeDashBin "mpc-lyrik" ''MPD_PORT=${toString lyrik.mpdPort} ${pkgs.mpc_cli}/bin/mpc "$@"''; '') stations;
in in
{ {
imports = [ <stockholm/krebs/3modules/htgen.nix> ]; imports = [ <stockholm/krebs/3modules/htgen.nix> ];
@@ -52,43 +74,22 @@ in
users.extraUsers.radio.isSystemUser = true; users.extraUsers.radio.isSystemUser = true;
containers.lyrik = {
autoStart = true;
config = {config, pkgs, ...}: {
services.mpd = {
enable = true;
network.port = lyrik.mpdPort;
extraConfig = ''
log_level "default"
audio_output {
name "Lyrik-Radio"
type "httpd"
encoder "vorbis"
port "${toString lyrik.streamPort}"
bitrate "128"
format "44100:16:2"
always_on "yes"
tags "yes"
}
'';
};
};
};
krebs.htgen.radio = { krebs.htgen.radio = {
port = htgenPort; port = htgenPort;
user.name = "radio"; user.name = "radio";
script = ''. ${pkgs.writers.writeDash "meinskript" '' script = ''. ${pkgs.writers.writeDash "meinskript" ''
send200() {
printf 'HTTP/1.1 200 OK\r\n'
printf 'Content-Type: text/html; charset=UTF-8\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
}
case "$Method $Request_URI" in case "$Method $Request_URI" in
"GET /lyrik/status") "GET /lyrik/status")
printf 'HTTP/1.1 200 OK\r\n' send200
printf 'Content-Type: text/html; charset=UTF-8\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
video_id="$( video_id="$(
MPD_PORT=${toString lyrik.mpdPort} ${pkgs.mpc_cli}/bin/mpc status -f %file% \ ${mpcs.lyrik}/bin/mpc-lyrik status -f %file% \
| head -n1 \ | head -n1 \
| grep -o 'id=[^&]*' \ | grep -o 'id=[^&]*' \
| sed 's/^id=//g' | sed 's/^id=//g'
@@ -97,18 +98,15 @@ in
${pkgs.youtube-dl}/bin/youtube-dl -j "https://www.youtube.com/watch?v=$video_id" \ ${pkgs.youtube-dl}/bin/youtube-dl -j "https://www.youtube.com/watch?v=$video_id" \
| ${pkgs.jq}/bin/jq -r '"% [\(.title)](\(.webpage_url))\n\n\(.description)"' \ | ${pkgs.jq}/bin/jq -r '"% [\(.title)](\(.webpage_url))\n\n\(.description)"' \
| sed 's/$/ /g' \ | sed 's/$/ /g' \
| ${pandoc}/bin/pandoc -s | ${pkgs.pandoc}/bin/pandoc -s
exit exit
;; ;;
"GET /lyrikline/status") "GET /lyrikline/status")
printf 'HTTP/1.1 200 OK\r\n' send200
printf 'Content-Type: text/html; charset=UTF-8\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
hash="$( hash="$(
MPD_PORT=${toString lyrikline.mpdPort} ${pkgs.mpc_cli}/bin/mpc status -f '%file%' \ ${mpcs.lyrikline}/bin/mpc-lyrikline status -f '%file%' \
| head -n 1 \ | head -n 1 \
| md5sum \ | md5sum \
| cut -d' ' -f 1 | cut -d' ' -f 1
@@ -119,21 +117,15 @@ in
exit exit
;; ;;
"POST /meddl/skip") "POST /meddl/skip")
printf 'HTTP/1.1 200 OK\r\n' send200
printf 'Content-Type: text/html; charset=UTF-8\r\n' ${mpcs.meddl}/bin/mpc-meddl next
printf 'Connection: close\r\n'
printf '\r\n'
${mpc-meddl}/bin/mpc-meddl next
exit exit
;; ;;
"GET /meddl/status") "GET /meddl/status")
printf 'HTTP/1.1 200 OK\r\n' send200
printf 'Content-Type: text/html; charset=UTF-8\r\n'
printf 'Connection: close\r\n'
printf '\r\n'
hash="$( hash="$(
MPD_PORT=${toString meddl.mpdPort} ${pkgs.mpc_cli}/bin/mpc status -f '%file%' \ ${mpcs.meddl}/bin/mpc-meddl status -f '%file%' \
| head -n 1 \ | head -n 1 \
| md5sum \ | md5sum \
| cut -d' ' -f 1 | cut -d' ' -f 1
@@ -147,46 +139,20 @@ in
''}''; ''}'';
}; };
containers.meddl = { containers = lib.mapAttrs (name: station: {
autoStart = true; autoStart = true;
config = {config, pkgs, ...}: { config = {config, pkgs, ...}: {
services.mpd = { services.mpd = {
enable = true; enable = true;
network.port = meddl.mpdPort; network.port = station.mpdPort;
extraConfig = ''
log_level "default"
volume_normalization "yes"
audio_output {
name "DrachenLord Radio"
type "httpd"
encoder "vorbis"
port "${toString meddl.streamPort}"
bitrate "128"
format "44100:16:2"
always_on "yes"
tags "yes"
}
'';
};
};
};
containers.lyrikline = {
autoStart = true;
config = {config, pkgs, ...}: {
services.mpd = {
enable = true;
network.port = lyrikline.mpdPort;
extraConfig = '' extraConfig = ''
log_level "default" log_level "default"
audio_output { audio_output {
name "lyrikline.org Radio" name "${name}"
type "httpd" type "httpd"
encoder "vorbis" encoder "vorbis"
port "${toString lyrikline.streamPort}" port "${toString station.streamPort}"
bitrate "128" bitrate "128"
format "44100:16:2" format "44100:16:2"
always_on "yes" always_on "yes"
@@ -195,14 +161,16 @@ in
''; '';
}; };
}; };
}; }) stations;
environment.systemPackages = lib.attrValues mpcs;
systemd.services.lyrikline = { systemd.services.lyrikline = {
after = [ "container@lyrikline.service" ]; after = [ "container@lyrikline.service" ];
wantedBy = [ "container@lyrikline.service" ]; wantedBy = [ "container@lyrikline.service" ];
startAt = "*:00/5"; startAt = "*:00/5";
serviceConfig.User = config.users.extraUsers.radio.name; serviceConfig.User = config.users.extraUsers.radio.name;
preStart = "${mpc-lyrikline}/bin/mpc-lyrikline crop || :"; preStart = "${mpcs.lyrikline}/bin/mpc-lyrikline crop || :";
script = '' script = ''
set -efu set -efu
@@ -221,32 +189,33 @@ in
echo "$poem_file ($hash) -> $poem_url" echo "$poem_file ($hash) -> $poem_url"
echo "$poem_url" > "${radioStore}/$hash" echo "$poem_url" > "${radioStore}/$hash"
${mpc-lyrikline}/bin/mpc-lyrikline add "$poem_file" ${mpcs.lyrikline}/bin/mpc-lyrikline add "$poem_file"
done done
${mpc-lyrikline}/bin/mpc-lyrikline play ${mpcs.lyrikline}/bin/mpc-lyrikline play
''; '';
}; };
systemd.services.lyrik = { systemd.services.lyrik = {
after = [ "container@lyrik.service" ]; after = [ "container@lyrik.service" ];
wantedBy = [ "container@lyrik.service" ]; wantedBy = [ "container@lyrik.service" ];
preStart = "${mpc-lyrik}/bin/mpc-lyrik crop || :"; preStart = "${mpcs.lyrik}/bin/mpc-lyrik crop || :";
restartIfChanged = true; restartIfChanged = true;
serviceConfig.User = config.users.extraUsers.radio.name; serviceConfig.User = config.users.extraUsers.radio.name;
script = script =
let let
invidious = "https://invidious.silkky.cloud";
videoIds = import <niveum/lib/hot-rotation/lyrik.nix>; videoIds = import <niveum/lib/hot-rotation/lyrik.nix>;
streams = lib.concatMapStringsSep "\n" (id: "https://au.ytprivate.com/latest_version?id=${id}&itag=251") videoIds; streams = lib.concatMapStringsSep "\n" (id: "${invidious}/latest_version?id=${id}&itag=251") videoIds;
streamsFile = pkgs.writeText "hotrot" streams; streamsFile = pkgs.writeText "hotrot" streams;
in '' in ''
set -efu set -efu
${mpc-lyrik}/bin/mpc-lyrik add < ${toString streamsFile} ${mpcs.lyrik}/bin/mpc-lyrik add < ${toString streamsFile}
${mpc-lyrik}/bin/mpc-lyrik crossfade 5 ${mpcs.lyrik}/bin/mpc-lyrik crossfade 5
${mpc-lyrik}/bin/mpc-lyrik random on ${mpcs.lyrik}/bin/mpc-lyrik random on
${mpc-lyrik}/bin/mpc-lyrik repeat on ${mpcs.lyrik}/bin/mpc-lyrik repeat on
${mpc-lyrik}/bin/mpc-lyrik play ${mpcs.lyrik}/bin/mpc-lyrik play
''; '';
}; };
@@ -256,7 +225,7 @@ in
wantedBy = [ "container@meddl.service" ]; wantedBy = [ "container@meddl.service" ];
startAt = "*:00/10"; startAt = "*:00/10";
serviceConfig.User = config.users.extraUsers.radio.name; serviceConfig.User = config.users.extraUsers.radio.name;
preStart = "${mpc-meddl}/bin/mpc-meddl crop || :"; preStart = "${mpcs.meddl}/bin/mpc-meddl crop || :";
script = '' script = ''
set -efu set -efu
host=http://antenne-asb.ga host=http://antenne-asb.ga
@@ -278,25 +247,35 @@ in
echo "$song_url ($hash) -> $song" echo "$song_url ($hash) -> $song"
echo "$song" > "${radioStore}/$hash" echo "$song" > "${radioStore}/$hash"
${mpc-meddl}/bin/mpc-meddl add "$song_url" ${mpcs.meddl}/bin/mpc-meddl add "$song_url"
done done
${mpc-meddl}/bin/mpc-meddl play ${mpcs.meddl}/bin/mpc-meddl play
''; '';
}; };
environment.systemPackages = [ mpc-lyrikline mpc-lyrik mpc-meddl ]; services.nginx.virtualHosts."radio.xn--kiern-0qa.de" = {
enableACME = true;
services.nginx.virtualHosts."radio.xn--kiern-0qa.de".locations = { forceSSL = true;
"= /meddl/status".proxyPass = "http://127.0.0.1:${toString htgenPort}"; locations = lib.mkMerge (
"= /meddl/listen.ogg".proxyPass = "http://127.0.0.1:${toString meddl.streamPort}"; [
"= /meddl/skip".proxyPass = "http://127.0.0.1:${toString htgenPort}"; {
"= /lyrikline/status".proxyPass = "http://127.0.0.1:${toString htgenPort}"; "/".extraConfig = ''
"= /lyrikline/listen.ogg".proxyPass = "http://127.0.0.1:${toString lyrikline.streamPort}"; default_type "text/html";
"= /lyrik/status".proxyPass = "http://127.0.0.1:${toString htgenPort}"; root ${pkgs.linkFarm "station-list" [{
"= /lyrik/listen.ogg".proxyPass = "http://127.0.0.1:${toString lyrik.streamPort}"; name = "index.html";
"= /lyrik.ogg".return = "301 http://radio.xn--kiern-0qa.de/lyrik/listen.ogg"; path = import ./station-list.nix { inherit pkgs lib stations; };
"= /meddl.ogg".return = "301 http://radio.xn--kiern-0qa.de/meddl/listen.ogg"; }]};
"= /lyrikline.ogg".return = "301 http://radio.xn--kiern-0qa.de/lyrikline/listen.ogg"; index index.html;
'';
# skip
"= /meddl/skip".proxyPass = "http://127.0.0.1:${toString htgenPort}";
}
] ++ (lib.mapAttrsToList (name: station: {
"= /${name}/status".proxyPass = "http://127.0.0.1:${toString htgenPort}";
"= /${name}/listen.ogg".proxyPass = "http://127.0.0.1:${toString station.streamPort}";
"= /${name}.ogg".return = "301 http://radio.xn--kiern-0qa.de/${name}/listen.ogg"; # legacy
}) stations)
);
}; };
} }

View File

@@ -0,0 +1,43 @@
{ pkgs, lib, stations }:
let
theStations = lib.mapAttrsToList (name: value: value // {name = name;}) stations;
in
pkgs.writeText "index.html" ''
<!doctype html>
<html>
<head>
<title>radio.kierán</title>
<link
rel="stylesheet"
href="//cdn.rawgit.com/necolas/normalize.css/master/normalize.css"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.2/css/bulma.min.css"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf-8" />
</head>
<body>
<main class="section">
<div class="subtitle is-3">Welcome to</div>
<h1 class="title is-1">radio.kierán</h1>
<div class="columns is-multiline">
${lib.concatMapStringsSep "\n" (station: ''
<div class="column">
<div class="box">
<strong class="is-uppercase">${station.name}</strong>
(<a href="/${station.name}/status">status</a>, <a href="/${station.name}/listen.ogg">link</a>)
<p class="has-text-grey">${station.description}</p>
<hr/>
<audio style="width:100%" controls src="/${station.name}/listen.ogg"/>
</div>
</div>'') theStations
}
</div>
</main>
</body>
</html>
''

View File

@@ -42,18 +42,18 @@ in [
desc = "Diminutive from lassus (weary, faint, tired). A programming human. Doing superior professional art."; desc = "Diminutive from lassus (weary, faint, tired). A programming human. Doing superior professional art.";
} }
{ {
stream = "http://radio.xn--kiern-0qa.de/meddl/listen.ogg"; stream = "https://radio.xn--kiern-0qa.de/meddl/listen.ogg";
station = "Meddl"; station = "Meddl";
logo = "https://antenne-asb.ga/logo.png"; logo = "https://antenne-asb.ga/logo.png";
desc = "Forked from antenne-asb.ga: Radiosender zum Youtuber Drachenlord. Hier läuft den ganzen Tag Drachenlord Musik von Haidern oder Podcasts zum Lord."; desc = "Forked from antenne-asb.ga: Radiosender zum Youtuber Drachenlord. Hier läuft den ganzen Tag Drachenlord Musik von Haidern oder Podcasts zum Lord.";
} }
{ {
stream = "http://radio.xn--kiern-0qa.de/lyrik/listen.ogg"; stream = "https://radio.xn--kiern-0qa.de/lyrik/listen.ogg";
station = "Lyrik"; station = "Lyrik";
desc = "Lyrik-Lesung rund um die Uhr."; desc = "Lyrik-Lesung rund um die Uhr.";
} }
{ {
stream = "http://radio.xn--kiern-0qa.de/lyrikline/listen.ogg"; stream = "https://radio.xn--kiern-0qa.de/lyrikline/listen.ogg";
station = "Lyrikline"; station = "Lyrikline";
logo = "https://www.lyrikline.org/themes/lyrik/svg/Logo_lyrikline_pure.svg"; logo = "https://www.lyrikline.org/themes/lyrik/svg/Logo_lyrikline_pure.svg";
desc = "24/7 zufällige Wiedergaben von lyrikline.org."; desc = "24/7 zufällige Wiedergaben von lyrikline.org.";

View File

@@ -54,7 +54,7 @@ in
<niveum/configs/moodle-dl/borsfaye.nix> <niveum/configs/moodle-dl/borsfaye.nix>
<niveum/configs/save-space.nix> <niveum/configs/save-space.nix>
<niveum/configs/version.nix> <niveum/configs/version.nix>
<niveum/configs/radio.nix> <niveum/configs/radio>
<niveum/configs/gitea.nix> <niveum/configs/gitea.nix>
<niveum/configs/telegram-bots> <niveum/configs/telegram-bots>
<niveum/configs/weechat.nix> <niveum/configs/weechat.nix>