Synchronised Low Latency Multi-Client Network Audio
My flatmates and I have been trying for a long time to set up a synchronised network audio system so that we can listen to music from youtube and other sources together. Many, many avenues have been explored, including clients which just play a file at the same time, webRTC, websockets, netcat and many others. However, these methods proved very difficult to synchronise across an IP based network.
Finally, we have found a solution. It may not be optimum but performs well!
First, a warning
We did notice severe wifi problems when using this kind of multicast streaming. It would cause computers to randomly drop off the wifi and be unable to reconnect. It would also lag out SSH on the network. We're looking into IGMP snooping to sort this, (allows clients to 'subscribe' to multicast streams) and will update this post if we find anything.
The issue is that multicast is very expensive when transmitted over wifi, whereas over ethernet it is actually less expensive than normal unicast packets.
If you're not sure if this is a problem for you, try killing pulse audio and see if the problems stop:
pulseaudio -k
If you were running this on a pure ethernet LAN, however, it works flawlessly with no problems and a very small latency!
The Server
I used a clean Ubuntu Server 16.04 instance to set this up. Your experience with other flavours may vary.
Step 1 - Install required components. mpd, pulseaudio, vlc, nfs (for media access)
sudo apt install mpd pulseaudio vlc nfs-common
Setup pulseaudio.
sudo nano /etc/pulse/default.pa
#Add the following content at the end of the file to rtp stream media to the network
load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100
load-module module-rtp-send source=rtp.monitor
Start pulseaudio
pulseaudio -D
Find pulseaudio stream
sudo tcpdump -i eth0 #Your interface here
You'll see a lot of packets like this:
12:06:25.209396 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.216614 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.339596 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.346829 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.354058 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.361285 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.368519 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.375750 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
12:06:25.382990 IP 10.0.1.125.32787 > 224.0.0.56.46606: UDP, length 1292
The address and port in this case you would need to make a note of is:
224.0.0.56:46606
Make MPD config
mkdir -p ~/.config/mpd
cp /usr/share/doc/mpd/mpdconf.example ~/.config/mpd/mpd.conf
nano ~/.config/mpd/mpd.conf
(Change the line with the music_directory parameter to suit your music location)
music_directory "/mnt/josh/"
Start MPD (debug mode)
mpd --no-daemon --verbose --stdout ~/.config/mpd/mpd.conf
Debug mode is helpful to check whether it can find your music library correctly.
Start VLC on server
On the same server, start VLC acting as a netsync master
vlc --control netsync --netsync-master rtp://224.0.0.56:46356
On the clients, synchronise the ntp clocks to a known source
sudo ntpdate 1.uk.pool.ntp.org
On the clients, start VLC in netsync client mode
vlc --control netsync --netsync-master-ip 10.0.1.125 rtp://224.0.0.56:46356
Download an MPD client, e.g. mpc and start playing music.
Now, you should have synchronised music across multiple machines!