cursed
This commit is contained in:
parent
c696c80012
commit
9a3493bf0c
|
@ -1,21 +1,15 @@
|
||||||
{ ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
sink_name = "rtp-raspberry";
|
sink_name = "roc-raspberry";
|
||||||
description = "Raspberry Output";
|
description = "Raspberry ROC Output";
|
||||||
ip_addr = "100.118.202.64";
|
ip_addr = "100.118.202.64";
|
||||||
|
#ip_addr = "100.115.10.34";
|
||||||
in {
|
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 = ''
|
services.mpd.extraConfig = ''
|
||||||
audio_output {
|
audio_output {
|
||||||
type "pulse"
|
type "pipe"
|
||||||
name "${description}"
|
name "${description}"
|
||||||
target "${sink_name}"
|
command "${pkgs.roc-send-pcm}/bin/roc-send-pcm s16le 44.1k 2 ${ip_addr}"
|
||||||
server "127.0.0.1"
|
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ pkgs, lib, tree, ... }: {
|
{ pkgs, lib, tree, ... }: {
|
||||||
#imports = [ ./mpd-broadcast/broadcast.nix ];
|
imports = [ ./mpd-broadcast/broadcast.nix ];
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ mpc_cli ];
|
environment.systemPackages = with pkgs; [ mpc_cli ];
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,10 @@
|
||||||
|
|
||||||
profiles.laptop
|
profiles.laptop
|
||||||
|
|
||||||
#profiles.connectivity.bluetooth
|
# Bluetooth
|
||||||
|
profiles.connectivity.bluetooth
|
||||||
|
profiles.sound.pulseaudio.pulse-bluetooth
|
||||||
|
|
||||||
profiles.connectivity.network_manager
|
profiles.connectivity.network_manager
|
||||||
profiles.connectivity.ios
|
profiles.connectivity.ios
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
{ pkgs, tree, ... }: {
|
{ pkgs, tree, ... }: {
|
||||||
imports = [ ./mpd-music-sync.nix ] ++ (with tree; [
|
imports = [ ./mpd-music-sync.nix ];
|
||||||
profiles.sound.pulseaudio.pulse-recv-native-localhost
|
|
||||||
profiles.sound.pulseaudio.pulse-recv-rtp
|
|
||||||
]);
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [ mpc_cli roc-toolkit ];
|
environment.systemPackages = with pkgs; [ mpc_cli mpv roc-toolkit-patched ];
|
||||||
|
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /var/lib/mpd 0755 mpd mpd -"
|
"d /var/lib/mpd 0755 mpd mpd -"
|
||||||
|
|
|
@ -34,8 +34,16 @@
|
||||||
networking.useDHCP = true;
|
networking.useDHCP = true;
|
||||||
networking.wireless = {
|
networking.wireless = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
userControlled.enable = true;
|
||||||
environmentFile = "/secrets/wifi-env";
|
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;
|
sdImage.compressImage = lib.mkForce false;
|
||||||
|
|
|
@ -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; [
|
imports = with tree; [
|
||||||
profiles.connectivity.bluetooth
|
profiles.connectivity.bluetooth
|
||||||
|
|
||||||
|
@ -6,13 +25,50 @@
|
||||||
profiles.sound.pulseaudio.pulse-systemwide
|
profiles.sound.pulseaudio.pulse-systemwide
|
||||||
profiles.sound.pulseaudio.pulse-bluetooth
|
profiles.sound.pulseaudio.pulse-bluetooth
|
||||||
profiles.sound.pulseaudio.pulse-recv-native-localhost
|
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 = ''
|
hardware.pulseaudio.extraConfig = ''
|
||||||
load-module module-bluetooth-policy
|
|
||||||
load-module module-bluetooth-discover
|
|
||||||
set-default-sink bluez_card.3E_39_E7_B2_86_29
|
set-default-sink bluez_card.3E_39_E7_B2_86_29
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
p
|
|
15
hosts/raspberry/services/process-media-controls.py
Normal file
15
hosts/raspberry/services/process-media-controls.py
Normal file
|
@ -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))
|
|
@ -10,4 +10,7 @@ final: prev: {
|
||||||
multimc = prev.polymc.override {
|
multimc = prev.polymc.override {
|
||||||
msaClientID = "499546d9-bbfe-4b9b-a086-eb3d75afb78f";
|
msaClientID = "499546d9-bbfe-4b9b-a086-eb3d75afb78f";
|
||||||
};
|
};
|
||||||
|
roc-toolkit-patched = final.callPackage ./roc-toolkit-patched { };
|
||||||
|
roc-send-pcm = final.callPackage ./roc-send-pcm { };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
9
overlay/roc-send-pcm/default.nix
Normal file
9
overlay/roc-send-pcm/default.nix
Normal file
|
@ -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
|
||||||
|
''
|
68
overlay/roc-toolkit-patched/default.nix
Normal file
68
overlay/roc-toolkit-patched/default.nix
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{ ... }: {
|
{ ... }: {
|
||||||
hardware.pulseaudio = {
|
hardware.pulseaudio = {
|
||||||
extraConfig = ''
|
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
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue