Last active
April 14, 2025 18:20
-
-
Save entropie/b4fe305a8537b9453d0fb71fdc99dbcd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ config, lib, pkgs, ... }: | |
# Headless Mopidy + Icecast Streaming Setup on NixOS | |
# | |
# Minimal and robust audio streaming setup using Mopidy and Icecast. | |
# Streams MP3 audio from Mopidy to Icecast (/mpd.mp3) using a clean GStreamer pipeline. | |
# No local audio output — pure network streaming. | |
# | |
# For example: use this setup to run a local home audio "radio" stream | |
# that you can cast to Chromecast devices or play on any networked media player. | |
# | |
# The best: its mpd compatible | |
let | |
mopidyUser = "mopidy"; | |
mopidyGroup = "mopidy"; | |
mpdGroup = "mpd"; | |
icecastUser = "icecast"; | |
icecastGroup = "icecast"; | |
musicBaseDir = "/srv/mopidy/music"; | |
mopidyDataDir = "/srv/mopidy"; | |
mopidyConfPath = "${mopidyDataDir}/mopidy.conf"; | |
icecastIp = "192.168.1.3"; | |
icecastPort = 13337; | |
icecastPassword = "hackme"; | |
mopidyOutput = '' | |
audioresample ! audioconvert ! audio/x-raw,rate=44100,channels=2 ! lamemp3enc quality=0 bitrate=192 cbr=true ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=2097152 ! shout2send async=true mount=/mpd.mp3 ip=${icecastIp} port=${toString icecastPort} password=${icecastPassword} | |
''; | |
in | |
{ | |
fileSystems."${musicBaseDir}/audiobooks" = { | |
device = "/home/media/audiobooks"; | |
options = [ "bind" ]; | |
}; | |
fileSystems."${musicBaseDir}/music" = { | |
device = "/home/media/music"; | |
options = [ "bind" ]; | |
}; | |
users.users.${mopidyUser} = { | |
isSystemUser = true; | |
group = mopidyGroup; | |
createHome = true; | |
extraGroups = [ "audio" "users" mpdGroup ]; | |
}; | |
users.groups.${mpdGroup} = {}; | |
services.mopidy = { | |
enable = true; | |
extraConfigFiles = [ mopidyConfPath ]; | |
dataDir = mopidyDataDir; | |
extensionPackages = with pkgs; [ | |
mopidy-mpd | |
# mopidy-local | |
# mopidy-spotify | |
]; | |
configuration = "\n\n"; # Wird durch activationScript überschrieben | |
}; | |
system.activationScripts.mopidyConf = { | |
text = '' | |
install -Dm775 ${pkgs.writeText "mopidy.conf" '' | |
[audio] | |
output = ${mopidyOutput} | |
[mpd] | |
enabled = true | |
hostname = 0.0.0.0 | |
port = 6600 | |
[file] | |
media_dirs = ${musicBaseDir} | |
''} ${mopidyConfPath} | |
chmod 0777 ${mopidyDataDir} | |
chown ${mopidyUser}:${mpdGroup} ${mopidyConfPath} | |
''; | |
}; | |
systemd.tmpfiles.rules = [ | |
"d ${mopidyDataDir} 0775 ${mopidyUser} ${mpdGroup} -" | |
"f ${mopidyConfPath} 0775 ${mopidyUser} ${mpdGroup} -" | |
]; | |
users.users.${icecastUser} = { | |
isSystemUser = true; | |
group = icecastGroup; | |
}; | |
users.groups.${icecastGroup} = {}; | |
services.icecast = { | |
enable = true; | |
hostname = icecastIp; | |
admin = { | |
user = "admin"; | |
password = icecastPassword; | |
}; | |
user = icecastUser; | |
group = icecastGroup; | |
logDir = "/var/log/icecast"; | |
listen = { | |
address = "0.0.0.0"; | |
port = icecastPort; | |
}; | |
extraConf = '' | |
<limits> | |
<clients>100</clients> | |
<sources>2</sources> | |
</limits> | |
<mount> | |
<mount-name>/mpd.mp3</mount-name> | |
<password>${icecastPassword}</password> | |
</mount> | |
''; | |
}; | |
environment.systemPackages = with pkgs; [ | |
mpc | |
ncmpcpp | |
lame | |
mopidy | |
icecast | |
]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment