I enjoy listening to music on records but unfortunately also enjoy having a wireless speaker system. This presents a problem, as Sonos speakers have no form of analog input without buying some absurdly expensive converter device (hundreds of dollars). No bueno.
Instead, I decided to take matters into my own hands by using a Raspberry Pi to convert my analog record signal into a digital stream. This stream can then be easily sent over to the Sonos speakers to play. This page is loosely based off of this guide by
replyreb on Instructables, however I've cut out a bunch of the setup steps for simplicity and added a few tweaks of my own.
This guide isn't too resource intensive however you will need at least two things to make this work:
- Raspberry Pi
- Through my experience I've found the original Raspberry Pi was too underpowered to handle streaming properly. Upon upgrading to a Raspberry Pi 4 everything seems to work great, with minimal latency and no interruptions so far.
- Behringer UCA202 or similar USB audio interface
- I use this interface but I can imagine any kind of USB audio card with an RCA input will work just as well. Be sure to check for linux drivers before buying something different.
Before proceeding to the next step, ensure your Raspberry Pi is running Raspbian, you have SSH access, and your USB audio card is connected to both the Raspberry Pi and your record player.
Raspberry Pi Setup
With our equipment set up, let's dive into the software. We'll be using a combination of
darkice to set up an HTTP audio stream that can be played on our Sonos (or any other device).
First you'll need to SSH into your Raspberry Pi and install both packages:
$ sudo apt install icecast2 darkice
Next we'll need to figure out the device identifier for our USB audio card. We'll use the
arecord -l which will list out each audio device available on the Pi:
$ arecord -l **** List of CAPTURE Hardware Devices **** card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio] Subdevices: 0/1 Subdevice #0: subdevice #0
From this output we can see the ID is
1 (looking at
card 1 for the number). Once you have this it's a good idea to test out your setup by recording a sample
.wav file to ensure the audio interface is working. Spin something on your record player and run the following command:
$ arecord -D plughw:1,0 -f cd temp.wav
ctrl+c out of it after 30 seconds or so of playback, copy the file to your local machine, and play it to see if you hear your record. If you don't you may need to go back and ensure everything is connected properly/you have the right device selected.
If all looks good we can spin up
# Start icecast $ sudo systemctl start icecast # Ensure icecast starts each time the system reboots $ sudo systemctl enable icecast
Next we'll configure darkice. Save the following config to
[general] duration = 0 # duration in s, 0 forever bufferSecs = 1 # 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) #quality = 1.0 # 1.0 is best quality (use only with vbr) format = mp3 # format. Choose 'vorbis' for OGG Vorbis bitrate = 320 # bitrate server = localhost # or IP port = 8000 # port for IceCast2 access password = helloWorld # source password for the IceCast2 server mountPoint = turntable.mp3 # mount point on the IceCast2 server .mp3 or .ogg name = Turntable highpass = 18 lowpass = 20000 description = Turntable
We'll also need to create a systemd script that starts darkice and loads the config file. Run
mkdir -p ~/.config/systemd/user and create the following file at
~/.config/systemd/user/turntable.service. I chose to make this a user-level systemd unit because it works better with my particular setup but you can probably make it systemwide without issue. Just move the file to
[Unit] Description=Turntable stream [Service] ExecStart=/usr/bin/darkice -c /etc/darkice.cfg [Install] WantedBy=default.target
If you decide to use the user-level service, make sure you enable lingering to ensure that the unit starts up when your system starts up (not when your user logs in):
loginctl enable-linger [your username]
If all looks good you should be able to spin up darkice like so:
$ systemctl --user start darkice $ systemctl --user enable darkice
At this point you should be able to log into the icecast UI at
If you click on the M3U link in the top right you should be able to begin listening to your record player's streaming audio. Awesome! If you're on a Mac you can import this file into Music.app and stream to your Sonos via Airplay. This works, but can be a bit clunky since the M3U file won't sync to other devices. Read on for more details...
I was a bit frustrated with the above setup as it was kind of annoying to have to use my laptop to connect my Sonos to the record player stream. After a while of being stuck, I finally came across a solution using a combination of iOS' Shortcuts app and the soco library for Python.
In a nutshell, I've created a shortcut on my phone that will ssh into my Raspberry Pi and execute a Python script. This Python script then connects to the Sonos speaker I usually use and instructs it to connect to the turntable stream. Voila, a convenient one-button method to start listening to my record player without having to involve fussing with a laptop/tMusic.app.
Here's the python script:
import soco import time x = soco.SoCo('[sonos IP address]') x.play_uri('http://[pi IP address]:8000/turntable.mp3.m3u')
And here's the iOS shortcut: