Start of icecast mpd nix article and cleanup
This commit is contained in:
parent
cc021ec002
commit
c2ce6c19f9
175
content/rambles/mpd-and-icecast-on-nix.md
Normal file
175
content/rambles/mpd-and-icecast-on-nix.md
Normal file
|
@ -0,0 +1,175 @@
|
|||
---
|
||||
title: "Mpd and Icecast on Nix"
|
||||
date: "2022-11-06T22:11:10+01:00"
|
||||
author: "$HUMANOID"
|
||||
tags: ["nix", "linux"]
|
||||
description: "Ramble about setting up MPD + Icecast on NixOS"
|
||||
---
|
||||
# Introduction
|
||||
|
||||
For quite some time now, I've been wanting to move my home server from Debian to
|
||||
NixOS. There were a few things that kept me from starting with the migration.
|
||||
The main one being that the Debian installation still worked reasonably well. I
|
||||
only had occasional hickups in regards to the two USB disks hooked up to my
|
||||
Raspberry Pi 4. Every now and then they'd disappear. My guess is that it was due
|
||||
to power draw as it would consistently happen when putting heavy IO loads on
|
||||
either disk. One of these disks is home to my music collection and used by my
|
||||
internet radio setup (in other words, the main thing I listen to when at home).
|
||||
And this nicely brings my to my next issue.
|
||||
|
||||
{{< img class="stickers" src="/images/graphs/radio.png" mouse="Flowchart demonstrating software stack">}}
|
||||
|
||||
This radio consists of an MPD instance streaming to an Icecast2 instance,
|
||||
being reverse proxied through an NGINX instance (future plans include managing
|
||||
the music collection through Git Annex...). I have tried setting up MPD on NixOS
|
||||
in the past, but couldn't get it to work for some odd reason. I don't remember
|
||||
why I never managed it. I just know that I gave up after a few hours. Today I
|
||||
decided to spend as much time as necessary to get at least the MPD + Icecast2
|
||||
portion to work. The rest of this post will be detailing how I went about
|
||||
setting configuring MPD + Icecast2 on NixOS as there were a few non-obvious
|
||||
things I bumped into.
|
||||
|
||||
# Setting up MPD
|
||||
|
||||
To prevent my `/etc/nixos/configuration.nix` from ballooning into absurdity,
|
||||
you'll want to create something like a `/etc/nixos/services/radio.nix` file
|
||||
containing everything related to the radio stack. This file is then imported in
|
||||
`/etc/nixos/configration.nix` in the `imports` section as follows:
|
||||
|
||||
```nix
|
||||
{ config, pkgs, ... }: {
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
./drives.nix
|
||||
./services/radio.nix
|
||||
|
||||
...
|
||||
|
||||
];
|
||||
...
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
The first thing you'll want to do is enable the MPD service:
|
||||
```nix
|
||||
{ config, pkgs, ... }: {
|
||||
services.mpd = {
|
||||
enable = true;
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
From here, there are a few rather basic options that you'll want to set:
|
||||
```nix
|
||||
...
|
||||
musicDirectory = "/path/to/music-collection/";
|
||||
network.listenAddress = "any"; # not quite sure if this is needed
|
||||
...
|
||||
```
|
||||
|
||||
At the `extraConfig` section is where things get interesting. Here I assumed you
|
||||
could point Nix to an existing config file with `(builtins.readFile
|
||||
/path/to/mpd.conf)` but it seems I am wrong. It doesn't throw any errors when
|
||||
switching to a new build, but it doesn't read the given config file either. I'm
|
||||
probably missing something here. Please shout at me if you happen to know what
|
||||
it is.
|
||||
|
||||
Regardless, you're going to want to add at least one audio output method. Since
|
||||
we're going to make MPD talk to Icecast2, we're going to add `audio_output`
|
||||
section of type "shout":
|
||||
|
||||
```nix
|
||||
...
|
||||
musicDirectory = "/path/to/music-collection/";
|
||||
extraConfig = ''
|
||||
audio_output {
|
||||
type "shout"
|
||||
encoder "vorbis" # FOSS codec for the win
|
||||
name "My Shouty Stream"
|
||||
host "<name found in the networking.hostName variable>"
|
||||
port "8000" # or use whatever meme you like
|
||||
mount "/mpd.ogg"
|
||||
password "hunter2"
|
||||
quality "5.0"
|
||||
format "44100:16:2"
|
||||
genre "Rythmic Noise!"
|
||||
protocol "icecast2"
|
||||
}
|
||||
'';
|
||||
};
|
||||
...
|
||||
```
|
||||
|
||||
Please don't take this snippet as gospel and read through the MPD configuration.
|
||||
Whatever is found in `extraConfig` will be directly given to MPD as if through
|
||||
`/etc/mpd.conf` on e.g. Debian. For instance, if you only locally want to listen
|
||||
to your music through say PulseAudio, than you'll need a corresponding output
|
||||
section.
|
||||
|
||||
{{< start-details summary="Example PulseAudio configuration I have on my laptop" >}}
|
||||
```conf
|
||||
...
|
||||
audio_output {
|
||||
type "pulse"
|
||||
name "Pulse output"
|
||||
audio_output_format "44100:16:2"
|
||||
samplerate_converter "Medium Sinc Interpolator"
|
||||
mixer_type "software"
|
||||
replaygain "album"
|
||||
volume_normalization "no"
|
||||
}
|
||||
...
|
||||
```
|
||||
{{< end-details >}}
|
||||
|
||||
## Mounting a music disk
|
||||
|
||||
In order to automount a disk on NixOS, add an expression something like the
|
||||
following (indirectly) in your `/etc/nixos/configration.nix`:
|
||||
|
||||
```nix
|
||||
fileSystems."/srv/music" = {
|
||||
device = "/dev/sdb1"; # assuming that sdb1 is the partition with your music on it
|
||||
# device = "/dev/disk/by-label/Sauserer"; # or ideally, if you have a labelled disk
|
||||
fsType = "ext4"; # assuming it has a ext4 filesystem on it
|
||||
};
|
||||
```
|
||||
I have my drives listed in `/etc/nixos/drives.nix` and import that in my
|
||||
`configration.nix`
|
||||
|
||||
# Setting up Icecast2
|
||||
|
||||
The next step is to set up Icecast2. Same as with MPD, the first thing you'll
|
||||
want to do is enable it:
|
||||
|
||||
```nix
|
||||
...
|
||||
services.icecast = {
|
||||
enable = true;
|
||||
extraConf = ''
|
||||
<location>Floating around in an example configuration snippet on the internet</location>
|
||||
<admin>icemaster@localhost</admin>
|
||||
<authentication>
|
||||
<source-password>hunter2</source-password>
|
||||
<relay-password>even-more-super-secret-password</relay-password>
|
||||
</authentication>
|
||||
|
||||
<limits>
|
||||
<clients>100</clients>
|
||||
<sources>2</sources>
|
||||
<queue-size>524288</queue-size>
|
||||
<client-timeout>30</client-timeout>
|
||||
<header-timeout>15</header-timeout>
|
||||
<source-timeout>10</source-timeout>
|
||||
<burst-on-connect>1</burst-on-connect>
|
||||
<burst-size>65535</burst-size>
|
||||
</limits>
|
||||
'';
|
||||
hostname = "hostname:8000";
|
||||
listen.port = 8000;
|
||||
admin.password = "it gives me a headache that I can't get Nix to read this from a file";
|
||||
};
|
||||
}
|
||||
```
|
|
@ -63,7 +63,7 @@ I ran DWM as my main window manger for over a year before having issues with
|
|||
some fullscreen applications and the JetBrains suite, which I had to use for
|
||||
college activities.
|
||||
|
||||
{{< img class="stickers" link="https://xkcd.com/1806/" src="/images/xkcd/borrow_your_laptop.png" >}}
|
||||
{{< img link="https://xkcd.com/1806/" src="/images/xkcd/borrow_your_laptop.png" >}}
|
||||
|
||||
I decided to give AwesomeWM another shot after having figured out what I want
|
||||
from a tiling window manger. This time I managed to get something that worked
|
||||
|
@ -113,7 +113,7 @@ and I decided to dive into learning the language with the goal of being able to
|
|||
fully understand my monstrous 384 line config file (586 lines including the
|
||||
documentation in commented sections).
|
||||
|
||||
{{< img class="stickers" src="/images/config_length.png" >}}
|
||||
{{< img src="/images/config_length.png" >}}
|
||||
|
||||
I don't fully understand it yet at the time of writing, but I do understand it
|
||||
a hell of a lot better than when I produced most of those 300 lines.
|
||||
|
|
BIN
static/images/graphs/radio.png
Normal file
BIN
static/images/graphs/radio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit 8122d5eb1ae06319cfc007454cd1ad46658aef1c
|
||||
Subproject commit 5251fa45a81337e7cf0a4d61f373d31d6c1ed1b7
|
Loading…
Reference in a new issue