From 9a3493bf0cc4e9d01b2686fbeb087a90ecd749f2 Mon Sep 17 00:00:00 2001 From: ChaotiCryptidz Date: Wed, 26 Jan 2022 23:05:24 +0000 Subject: [PATCH] cursed --- .../mpd-broadcast/hosts/raspberry.nix | 18 ++--- hosts/hetzner-vm/services/mpd.nix | 2 +- hosts/lappy/lappy.nix | 5 +- hosts/lappy/profiles/mpd.nix | 7 +- hosts/raspberry/raspberry.nix | 10 ++- hosts/raspberry/services/mpd-recv.nix | 66 ++++++++++++++++-- .../services/process-media-controls.py | 15 ++++ overlay/default.nix | 3 + overlay/roc-send-pcm/default.nix | 9 +++ overlay/roc-toolkit-patched/default.nix | 68 +++++++++++++++++++ profiles/sound/pulseaudio/pulse-recv-rtp.nix | 2 +- 11 files changed, 179 insertions(+), 26 deletions(-) create mode 100644 hosts/raspberry/services/process-media-controls.py create mode 100644 overlay/roc-send-pcm/default.nix create mode 100644 overlay/roc-toolkit-patched/default.nix diff --git a/hosts/hetzner-vm/services/mpd-broadcast/hosts/raspberry.nix b/hosts/hetzner-vm/services/mpd-broadcast/hosts/raspberry.nix index 72f8e5d..8e1da59 100644 --- a/hosts/hetzner-vm/services/mpd-broadcast/hosts/raspberry.nix +++ b/hosts/hetzner-vm/services/mpd-broadcast/hosts/raspberry.nix @@ -1,21 +1,15 @@ -{ ... }: +{ pkgs, ... }: let - sink_name = "rtp-raspberry"; - description = "Raspberry Output"; + sink_name = "roc-raspberry"; + description = "Raspberry ROC Output"; ip_addr = "100.118.202.64"; + #ip_addr = "100.115.10.34"; in { - hardware.pulseaudio = { - extraConfig = '' - load-module module-null-sink sink_name=${sink_name} sink_properties="device.description='${description}'" - load-module module-rtp-send source=${sink_name}.monitor destination_ip=${ip_addr} - ''; - }; services.mpd.extraConfig = '' audio_output { - type "pulse" + type "pipe" name "${description}" - target "${sink_name}" - server "127.0.0.1" + command "${pkgs.roc-send-pcm}/bin/roc-send-pcm s16le 44.1k 2 ${ip_addr}" } ''; } diff --git a/hosts/hetzner-vm/services/mpd.nix b/hosts/hetzner-vm/services/mpd.nix index b3ff667..25b495d 100644 --- a/hosts/hetzner-vm/services/mpd.nix +++ b/hosts/hetzner-vm/services/mpd.nix @@ -1,5 +1,5 @@ { pkgs, lib, tree, ... }: { - #imports = [ ./mpd-broadcast/broadcast.nix ]; + imports = [ ./mpd-broadcast/broadcast.nix ]; environment.systemPackages = with pkgs; [ mpc_cli ]; diff --git a/hosts/lappy/lappy.nix b/hosts/lappy/lappy.nix index f1dc187..7f02e00 100644 --- a/hosts/lappy/lappy.nix +++ b/hosts/lappy/lappy.nix @@ -14,7 +14,10 @@ profiles.laptop - #profiles.connectivity.bluetooth + # Bluetooth + profiles.connectivity.bluetooth + profiles.sound.pulseaudio.pulse-bluetooth + profiles.connectivity.network_manager profiles.connectivity.ios diff --git a/hosts/lappy/profiles/mpd.nix b/hosts/lappy/profiles/mpd.nix index b52f367..87f85fb 100644 --- a/hosts/lappy/profiles/mpd.nix +++ b/hosts/lappy/profiles/mpd.nix @@ -1,10 +1,7 @@ { pkgs, tree, ... }: { - imports = [ ./mpd-music-sync.nix ] ++ (with tree; [ - profiles.sound.pulseaudio.pulse-recv-native-localhost - profiles.sound.pulseaudio.pulse-recv-rtp - ]); + imports = [ ./mpd-music-sync.nix ]; - environment.systemPackages = with pkgs; [ mpc_cli roc-toolkit ]; + environment.systemPackages = with pkgs; [ mpc_cli mpv roc-toolkit-patched ]; systemd.tmpfiles.rules = [ "d /var/lib/mpd 0755 mpd mpd -" diff --git a/hosts/raspberry/raspberry.nix b/hosts/raspberry/raspberry.nix index 4fa616c..1dab67f 100644 --- a/hosts/raspberry/raspberry.nix +++ b/hosts/raspberry/raspberry.nix @@ -34,8 +34,16 @@ networking.useDHCP = true; networking.wireless = { enable = true; + userControlled.enable = true; environmentFile = "/secrets/wifi-env"; - networks.BT-JGA898.psk = "@PSK_HOME@"; + networks.BT-JGA898 = { + priority = 10; + psk = "@PSK_HOME@"; + }; + networks."Kitteh iPhone" = { + priority = 100; + psk = "@PSK_HOTSPOT@"; + }; }; sdImage.compressImage = lib.mkForce false; diff --git a/hosts/raspberry/services/mpd-recv.nix b/hosts/raspberry/services/mpd-recv.nix index e53ed0a..b67bbf1 100644 --- a/hosts/raspberry/services/mpd-recv.nix +++ b/hosts/raspberry/services/mpd-recv.nix @@ -1,4 +1,23 @@ -{ tree, ... }: { +{ tree, pkgs, ... }: +let + process-media-controls = pkgs.writeText "process-media-controls" '' + import asyncio + import os + from evdev import InputDevice, categorize, ecodes + + dev = InputDevice('/dev/input/event0') + + async def scanner(dev): + async for ev in dev.async_read_loop(): + if ev.type == ecodes.EV_KEY: + if ev.code in [ecodes.KEY_PLAYCD, ecodes.KEY_PAUSECD] and ev.value == 0: + print("Play/Pause Pressed") + os.system("pactl set-sink-mute @DEFAULT_SINK@ toggle") + + loop = asyncio.get_event_loop() + loop.run_until_complete(scanner(dev)) + ''; +in { imports = with tree; [ profiles.connectivity.bluetooth @@ -6,13 +25,50 @@ profiles.sound.pulseaudio.pulse-systemwide profiles.sound.pulseaudio.pulse-bluetooth profiles.sound.pulseaudio.pulse-recv-native-localhost - profiles.sound.pulseaudio.pulse-recv-rtp ]; + systemd = { + services.roc-recv = { + requires = [ "network.target" "pulseaudio.service" ]; + after = [ "network.target" "pulseaudio.service" ]; + wantedBy = [ "multi-user.target" ]; + script = '' + PULSE_SERVER=127.0.0.1 ${pkgs.roc-toolkit-patched}/bin/roc-recv --source "rtp:0.0.0.0:10001" + ''; + serviceConfig = { Restart = "always"; }; + }; + + services.process-media-controls = { + requires = [ "network.target" "pulseaudio.service" ]; + after = [ "network.target" "pulseaudio.service" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.pulseaudio ]; + script = let + python = pkgs.python39.withPackages + (ps: with ps; [ pkgs.python39Packages.evdev ]); + in '' + (${python.interpreter} ${process-media-controls}) || true + ''; + serviceConfig = { + Restart = "always"; + StartLimitAction = "none"; + }; + }; + + timers.bt-autoconnect = { + wantedBy = [ "timers.target" ]; + partOf = [ "bt-autoconnect.service" ]; + timerConfig.OnCalendar = "minutely"; + }; + services.bt-autoconnect = { + serviceConfig.Type = "oneshot"; + script = '' + ${pkgs.bluez}/bin/bluetoothctl connect 3E:39:E7:B2:86:29 || true + ''; + }; + }; + hardware.pulseaudio.extraConfig = '' - load-module module-bluetooth-policy - load-module module-bluetooth-discover set-default-sink bluez_card.3E_39_E7_B2_86_29 ''; } -p \ No newline at end of file diff --git a/hosts/raspberry/services/process-media-controls.py b/hosts/raspberry/services/process-media-controls.py new file mode 100644 index 0000000..d88cf02 --- /dev/null +++ b/hosts/raspberry/services/process-media-controls.py @@ -0,0 +1,15 @@ +import asyncio +import os +from evdev import InputDevice, categorize, ecodes + +dev = InputDevice('/dev/input/event0') + +async def scanner(dev): + async for ev in dev.async_read_loop(): + if ev.type == ecodes.EV_KEY: + if ev.code in [ecodes.KEY_PLAYCD, ecodes.KEY_PAUSECD] and ev.value == 0: + print("Play/Pause Pressed") + os.system("pactl set-sink-mute @DEFAULT_SINK@ toggle") + +loop = asyncio.get_event_loop() +loop.run_until_complete(scanner(dev)) \ No newline at end of file diff --git a/overlay/default.nix b/overlay/default.nix index 5f0b60d..c7baf01 100644 --- a/overlay/default.nix +++ b/overlay/default.nix @@ -10,4 +10,7 @@ final: prev: { multimc = prev.polymc.override { msaClientID = "499546d9-bbfe-4b9b-a086-eb3d75afb78f"; }; + roc-toolkit-patched = final.callPackage ./roc-toolkit-patched { }; + roc-send-pcm = final.callPackage ./roc-send-pcm { }; + } diff --git a/overlay/roc-send-pcm/default.nix b/overlay/roc-send-pcm/default.nix new file mode 100644 index 0000000..836bc19 --- /dev/null +++ b/overlay/roc-send-pcm/default.nix @@ -0,0 +1,9 @@ +{ pkgs, ... }: +pkgs.writeShellScriptBin "roc-send-pcm" '' + FORMAT=$1 + RATE=$2 + CHANNELS=$3 + IP_ADDR=$4 + + ${pkgs.ffmpeg}/bin/ffmpeg -f $FORMAT -ar $RATE -ac $CHANNELS -i /dev/stdin -f wav -y /dev/stdout | ${pkgs.roc-toolkit-patched}/bin/roc-send --source "rtp:$IP_ADDR:10001" --driver wav /dev/stdin +'' diff --git a/overlay/roc-toolkit-patched/default.nix b/overlay/roc-toolkit-patched/default.nix new file mode 100644 index 0000000..f445117 --- /dev/null +++ b/overlay/roc-toolkit-patched/default.nix @@ -0,0 +1,68 @@ +{ stdenv, + lib, + fetchFromGitHub, + sconsPackages, + ragel, + gengetopt, + pkg-config, + libuv, + openfecSupport ? true, + openfec, + libunwindSupport ? true, + libunwind, + pulseaudioSupport ? true, + libpulseaudio, + soxSupport ? true, + sox +}: + +stdenv.mkDerivation rec { + pname = "roc-toolkit"; + version = "0.1.5"; + + src = fetchFromGitHub { + owner = "roc-streaming"; + repo = "roc-toolkit"; + rev = "v${version}"; + sha256 = "sha256:1pld340zfch4p3qaf5anrspq7vmxrgf9ddsdsq92pk49axaaz19w"; + }; + + nativeBuildInputs = [ + sconsPackages.scons_3_0_1 + ragel + gengetopt + pkg-config + ]; + + buildInputs = [ + libuv + libunwind + openfec + libpulseaudio + sox + ]; + + sconsFlags = + [ "--build=${stdenv.buildPlatform.config}" + "--host=${stdenv.hostPlatform.config}" + "--prefix=${placeholder "out"}" + "--disable-tests" ] ++ + lib.optional (!soxSupport) "--disable-sox" ++ + lib.optional (!libunwindSupport) "--disable-libunwind" ++ + lib.optional (!pulseaudioSupport) "--disable-pulseaudio" ++ + (if (!openfecSupport) + then ["--disable-openfec"] + else [ "--with-libraries=${openfec}/lib" + "--with-openfec-includes=${openfec.dev}/include" ]); + + prePatch = lib.optionalString stdenv.isAarch64 + "sed -i 's/c++98/c++11/g' SConstruct"; + + meta = with lib; { + description = "Roc is a toolkit for real-time audio streaming over the network"; + homepage = "https://github.com/roc-streaming/roc-toolkit"; + license = licenses.mpl20; + maintainers = with maintainers; [ bgamari ]; + platforms = platforms.unix; + }; +} \ No newline at end of file diff --git a/profiles/sound/pulseaudio/pulse-recv-rtp.nix b/profiles/sound/pulseaudio/pulse-recv-rtp.nix index 90c62b4..9e80bc2 100644 --- a/profiles/sound/pulseaudio/pulse-recv-rtp.nix +++ b/profiles/sound/pulseaudio/pulse-recv-rtp.nix @@ -1,7 +1,7 @@ { ... }: { hardware.pulseaudio = { extraConfig = '' - load-module module-rtp-recv latency_msec=500 sap_address=0.0.0.0 + load-module module-rtp-recv latency_msec=5000 sap_address=0.0.0.0 ''; }; }