Streaming Vinyl Using Icecast, DarkIce, and a Raspberry Pi
I "recently" (within the past couple of years) started to collect vinyl. Collecting vinyl is a great way to own the music that I enjoy, it's fun to have something tangible to hold, album art work to admire again, etc. At the same time, I very much still stream music. It's convenient, portable, and a great way to discover new artists and songs.
I happen to have a few Raspberry Pi's (RPI) in my collection, some Sonos speakers, and was inspired by this Instructable to blend my analogue and digital world.
My setup is using an older Raspberry Pi 2 Model B and a Behringer U-PHONE UFO202. I am not using the UFO202 as a preamp, it is currently sitting further down the line. Below is how I went about streaming my turntable to the digital world.
Getting Started
Using the Raspberry Pi Imager, flash the Raspberry Pi OS Lite image. Configure the image to have SSH enabled and set the user name and password. Having SSH enabled allows the Pi to be configured without needing a monitor or keyboard.
I am using my router to assign a static IP to the RPI. A static IP is necessary for both connecting via SSH and exposing the stream to the outside world.
Configuring the PI
Before moving forward, make sure the RPI is up to date. This can be a little slow depending on the speed of both the RPI and SD card.
sudo apt update
sudo apt dist-upgrade
Configure the RPI, using raspi-config to only use 16 MB for the GPU memory. This is a headless RPI, so there's no need for GPU memory.
Verify the Sound Card
Verify that the sound card is properly being detected by running arecord -l. The output should be similar to:
**** List of CAPTURE Hardware Devices ****
card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
Installing Icecast2
Icecast is streaming media server and what the RPI will be running to stream the turntable. It can be installed from the pre-configured apt repositories by running sudo apt install icecast2.
When configuring, accept all the defaults. They can be changed later by editing /etc/icecast2/icecast.xml.
Installing DarkIce
DarkIce is a live audio streamer. It will be used to capture the input from the sound card, encode it, and send it to the Icecast server to stream. The Instructable used the precompiled deb page from https://github.com/x20mar/darkice-with-mp3-for-raspberry-pi/ but that is outdated. Instead, I compiled the latest DarkIce source on the RPI.
Installing Build Tools
Install the necessary tools for pulling and compiling the source from the apt repositories by running sudo apt install --install-recommends git libtool
Compiling with also need some additional libraries to compile with support. They are installed by running sudo apt install libmp3lame-dev libvorbis-dev libasound2-dev
Pulling the DarkIce Source
Using git, clone the DarkIce source into the home directory with git clone https://github.com/rafael2k/darkice.
Compiling DarkIce
Change directory into the "trunk", cd darkice/darkice/trunk/, and run the "autogen" script: ./autogen.sh. This will verify the necessary tools are installed and run any needed configuration. There may be some warnings but the script should execute successfully.
Verify that ALSA support is present looking for checking for alsa... yes in the output of the "autogen" script.
Next, compile the source using make. This will take some time on the RPI. Again, there my be some warnings but it should compile without issue.
Installing DarkIce
Finally, install DarkIce by running sudo make install. Verify DarkIce installed by running which darkice. The output should be:
/usr/local/bin/darkice
Configuring Icecast
With everything installed, it's time to configure Icecast. To do so, edit the configuration stored in /etc/icecast2/icecast.xml. For my needs, I changed:
- the "admin" address
- limit the number of "clients" to 5
- the "source-password", "admin-user", and "admin-password"
- hostname
- bound port 8000 to only be available for 127.0.0.1
- created a new socket for administrating / viewing the Icecast page
- configure the path to the SSL cert
Configuring SSL
If using a SSL cert, make sure that the certificate contains both the public keys and private key. This guide walks through using Let's Encrypt https://mediarealm.com.au/articles/icecast-https-ssl-setup-lets-encrypt/.
Configuring DarkIce
Now to configure DarkIce. Change directory back to the root home directory, cd ~ and create a "darkice.cfg" file with touch darkice.cfg.
Below is my "darkice.cfg" as reference. The password is omitted below, but on the RPI it matches what is defined in /etc/icecast2/icecast.xml.
[general]
duration = 0 # duration in s, 0 forever
bufferSecs = 5 # buffer, in seconds
reconnect = yes # reconnect if disconnected
[input]
device = plughw:1,0 # Soundcard device for the audio input
sampleRate = 44100 # sample rate 11025, 22050 or 44100
bitsPerSample = 16 # bits
channel = 2 # 2 = stereo
[icecast2-0]
bitrateMode = cbr # constant bit rate ('cbr' constant, 'abr' average)
format = mp3 # format. Choose 'vorbis' for OGG Vorbis
bitrate = 320 # bitrate
server = 127.0.0.1 # localhost or IP
port = 8000 # port for IceCast2 access
password = <source-password>
# source password for the IceCast2 server (there must not be a comment following the password)
mountPoint = vinyl.mp3 # mount point on the IceCast2 server .mp3 or .ogg
name = Turntable
description = Vinyl playing on the turntable
Testing It Out
Starting Icecast
With everything configured, start the Icecast server by running sudo service icecast2 start. If Icecast is running, you should be able to view the server page in the browser using the IP assigned to the RPI and the port defined in /etc/icecast2/icecast.xml.
If something is wrong, check the Icecast logs for any issues cat /var/log/icecast2/error.log.
Starting DarkIce
With Icecast running, its time to start DarkIce so that Icecast has something to stream. To do so, run sudo /usr/local/bin/darkice -c ~/darkice.cfg.
If everything is working correctly, DarkIce should be running in the terminal and on the Icecast Status page there should be a mount point. Open the stream exposed via the M3U and verify everything is streaming as expected. Make sure there's something going into the input.
Surviving a Reboot
Currently, only Icecast will restart when the RPI is rebooted. It's not convenient to have to log in after every reboot to start up DarkIce. To start up DarkIce, a "cron" job can be scheduled to run on reboot. A cron job can be added by running crontab -e.
Adding the below will run a job on reboot that sleeps for 30 seconds, and then starts DarkIce. Sleeping for 30 seconds gives the RPI enough time to make sure the sound card is ready. If its not, DarkIce will fail to start.
@reboot sleep 30 && sudo /usr/local/bin/darkice -c /home/<your-pi-user-id>/darkice.cfg
Reboot the RPI and wait for it to restart plus the additional sleep time. If the cron job is running, the Icecast Status page will show the DarkIce mount point. If it does not, check the cron logs for any issues cat /var/log/cron.
Hello World
I wanted to expose my Icecast server to the outside world. To do so, I both configured port forwarding on my router and set up a custom DNS entry with my domain registrar.
Streaming to Sonos
Finally, to connect up to Sonos, add the TuneIn service. Within the TuneIn service, under "My Radio Stations", add a new station. Set the "Streaming URL" to the URL of the DarkIce stream. The URL can be found in the M3U file.
If everything is connected correctly, the radio station should start streaming over the Sonos speakers. Bringing the analog vinyl into the digital world, sent out through Sonos speakers.