WiFiHiFi – How to run Music Player Daemon on an OpenWRT wifi router

Remember those old jukeboxes where pub guests could choose a song that was added to the playlist? Well, imagine a party at your house where all guests could do so via wifi using their own mobile devices! In this article I will show you how. They easiest setup is, of course, to run Music Player Daemon on the computer where the music is stored. You install a Music Player Client on your mobile device and connect it to this computer via wifi.
The setup I describe is interesting if you want to play music from a file server that is not connected to the wifi but is somewhere in the LAN. Once the setup works, you can listen to the music without your laptop being turned on all the time. The aim is to run Music Player Daemon directly on the wifi router so that different devices in the wifi network can create a common playlist. (Music Player Daemon is quite an old free software project. Read more about it in the project’s wiki [1] or on Wikipedia [2].)

What you need:

  1. A wifi router running the free operating system OpenWRT. We used the TP-LINK model TL-WR1043ND – the one that comes with a USB port.
  2. A supported USB sound card (e.g. the C-Media USB Headphone Set (3D SOUND)) and a cable connecting this sound card to your stereo.
  3. Storage: You can either plug a USB hub into the wifi router and then connect the sound card and a USB flash disk to it. Or you get your music storage from somewhere else in the local network. This is what I did, so here I’ll talk about a fileserver in the LAN.
  4. A notebook or PC to configure everything and to test your setup.
  5. An internet connection for the wifi router during setup.
Diagram of the described setup

The setup (click to enlarge)

Step 1: Install OpenWRT on the wifi router

We need to modify the wifi router first to be able to install additional software on it. When you buy the TP-Link router mentioned above, you don’t get it with OpenWRT preinstalled. So here is how you install it (some of it depends on the exact hardware you choose):

  1. To download the appropriate image for the hardware enter your device’s name on the wiki http://wiki.openwrt.org [3] and search. (It might not be the most user-friendly website you have ever seen.) For the TP-Link TL-WR1043ND I downloaded this image to my computer: http://downloads.openwrt.org/backfire/10.03.1/ar71xx/openwrt-ar71xx-tl-wr1043nd-v1-squashfs-factory.bin.
  2. Configure your computer’s LAN interface in a way that it has a fixed IP address: The router probably has got the 192.168.1.1, give your computer the 192.168.1.2/24.
  3. Open your browser, go to 192.168.1.1. Find the menu item that allows you to update the device’s firmware. Upload the OpenWRT image via the web interface. It will take a little moment, then the router will be back with a completely different web interface called “LuCI”. That’s OpenWRT.
  4. Change the password and configure it as a wifi router for your network. (As I don’t know your router’s hostname, in the commands below, I will call it “router”. So make sure to replace “router” with the hostname. Similarly, I called the user that accesses the file server via ssh “router”. “server-ip” and “fileserver” have to be replaced by your fileserver’s IP address.)
  5. Keep your cable connection to the router and connect a second network cable to it, so that it can access the internet.

Step 2: Install some extra software on the router

Connect to the router via ssh, then run:

root@router:~# opkg update
root@router:~# opkg install kmod-usb-audio kmod-sound-core
# If you want to keep your music on a fileserver:
root@router:~# opkg install sshfs rsync

Step 3: Set up the ssh connection between router and file server

The router will have to access some directories on your file server permanently via ssh. Let’s create the key and config for this. First, create a user on your file server, e.g. “router”.

root@fileserver:~# useradd -m -d /home/router -s /bin/bash router

Check the file permissions of the music directory. If necessary, add the router user to an additional group. On OpenWRT you use dropbear for ssh. The procedure is very similar to openssh. This is how you create a key on your router:

root@router:~# dropbearkey -t rsa -f ~/.ssh/router
root@router:~# dropbearkey -y -f ~/.ssh/router | grep "^ssh-rsa " > ~/.ssh/router.pub
root@router:~# scp ~/.ssh/router.pub root@fileserver:/home/router/
# on the file server:
root@fileserver:~# mkdir /home/router/.ssh && mv /home/router/router.pub /home/router/.ssh/authorized_keys
root@fileserver:~# chown -R router:router /home/router && chmod 750 /home/router/.ssh && chmod 600 /home/router/.ssh/authorized_keys

Create a new file called “config” on your router, in the directory /root/.ssh:

IdentitiesOnly yes
Host = HOSTNAME OF FILE SERVER
HostName = server-ip
User = router
Port = 22
IdentityFile /root/.ssh/router

Step 3: Mount some extra disk space

On the router there is not enough free space to install everything we need. We will therefore use some storage the file server offers us. (Replace the parts in capital letters with your own values.)

root@router:~# mkdir /tmp/mnt
root@router:~# /usr/bin/sshfs -o ssh_command="ssh -i /root/.ssh/router" -o follow_symlinks router@server-ip:/home/router/usr /tmp/mnt
root@router:~# /usr/bin/rsync -rLptgoD /usr/ /tmp/mnt
root@router:~# umount /tmp/mnt
root@router:~# /usr/bin/sshfs -o ssh_command="ssh -i /root/.ssh/router" -o nonempty -o follow_symlinks router@server-ip:/home/router/usr /usr
## Control if this step worked:
root@router:~# mount
router@server-ip:/home/router/usr on /usr type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,max_read=65536)

Step 4: Mount the remote music storage and configure the sound stuff

Now we will install mpd, mount the file server’s music directory to the router via the encrypted sshfs connection and configure mpd. (mpc is only needed when you want to make the router update the music database itself. See below.)

root@router:~# opkg install mpd mpc alsa-utils
root@router:~# mkdir /mnt/mpd
root@router:~# /usr/bin/sshfs -o ssh_command="ssh -i /root/.ssh/router" -o follow_symlinks router@server-ip:/home/router/mpd /mnt/mpd

Check if it worked. In addition to the line, you just saw, there should now be a new one similar to this one:

root@router:~# mount
router@server-ip:/home/router/mpd on /mnt/mpd type fuse.sshfs (rw,nosuid,nodev,relatime,user_id=0,group_id=0,max_read=65536)

Edit the configuration file of Music Player Daemon /etc/mpd.conf:

# /etc/mpd.conf for C-Media USB Headphone Set
# files
music_directory "/mnt/mpd/music"
playlist_directory "/mnt/mpd/playlists"
db_file "/mnt/mpd/database"
log_file "/mnt/mpd/log"
pid_file "/var/run/mpd.pid"
state_file "/mnt/mpd/state"
sticker_file "/mnt/mpd/sticker.sql"
# IP address of your router:
bind_to_address "XXX.YYY.ZZZ.XYZ"
# metadata
metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
# follow symlinks
follow_outside_symlinks "yes"
follow_inside_symlinks "yes"
# permissions
password "YOURPASSWORD@read,add,control,admin"
default_permissions ""
# mixer type
mixer_type "software"
# max connections
max_connections "30"
# input
input {
plugin "curl"
}
# output
audio_output {
type "alsa"
name "Generic USB Audio Device" # you can check this with alsamixer
device "hw:0,0" # optional
}
#EOF

Edit the file /etc/init.d/mpd and replace the line amixer set PCM 40 with this line: amixer set Speaker 150.

Step 5: Make the router check if everyting is fine and update the music database every night

You might want to restore your setup automatically, in case you reboot the router. Write a small script that checks if the remote directories are mounted and if Music Player Daemon is running. the file should be placed in /bin/music.sh. Run chmod u+x to make in executable.

#!/bin/sh
  if [ "$( mount | grep sshfs | grep /usr )" == "" ]; then
  /bin/sleep 2
  /usr/bin/sshfs -o ssh_command="ssh -i /root/.ssh/router" -o nonempty -o follow_symlinks router@fileserver:/home/router/usr /usr
fi

if [ "$( mount | grep sshfs | grep /mnt/mpd )" == "" ]; then
  /bin/sleep 2
  /usr/bin/sshfs -o ssh_command="ssh -i /root/.ssh/router" -o follow_symlinks router@fileserver:/home/router/mpd /mnt/mpd
fi

if [ "$( ps | grep $( cat /var/run/mpd.pid ) | grep mpd )" == "" ]; then
  /bin/sleep 10
  /usr/bin/test -x /usr/bin/mpd && /etc/init.d/mpd start
fi

#EOF

Enter the command crontab -e. Add the following two lines to update mpd’s database every night automatically:

05 05 * * * /usr/bin/test -x /usr/bin/mpc && /usr/bin/mpc -h server-ip -P YOUR_PASSWORD update
*/2 *  * * * /usr/bin/test -x /bin/music.sh && /bin/music.sh

When you save and quit the file, the new cron job will be installed.

Step 6: Connect client devices

You are ready to test your setup! Choose a device that has access to your wifi and install a Music Player client. On Linux, this could be gmpc, on Android I recommend MPDroid. There is a long list of client software for different operating systems in the MPD wiki [4]. (Even iphone users will have access. :) )

Step 7: Connect your friends and party

To make your next party’s guests choose music and add them directly to the playlist, you just give them the following information:

  • They have to install a client app.
  • Give them access to your wifi network,
  • the IP address of the router and
  • the password if you set one in /etc/mpd.conf.

Now turn your laptop off and enjoy! The wifi router and your guests will do the work! ;)

Links

[1]: http://mpd.wikia.com/wiki/Music_Player_Daemon_Wiki
[2]: Music Player Daemon on the English language Wikipedia: https://en.wikipedia.org/wiki/Music_Player_Daemon
[3]: http://wiki.openwrt.org
[4]: http://mpd.wikia.com/wiki/Clients