Winter project: daap radio station

In late October of last year, I had a tangle with gift wrap and a set of stairs, and I lost, breaking and dislocating my right ankle in the process. Ever since I’ve been stuck at home for the most part. First there was a the trip to the emergency room, where my broken, dislocated ankle was put back in proper position and put in a splint and cast. Next there was the surgery- added to my natural arsenal was a plate and some screws. Re-splint, re-cast. Finally, after enough time, I was told to wear a CAM boot, which incidentally weighs at least twice as much as a cast. So I’ve had a lot of time to consider my situation. (Actually not a lot of time- I made arrangements to work from home once I could sit in a chair and access a laptop.)

One thing I had wanted to experiment with was finding a way to improve my “radio station-” really just an FM transmitter connected to whatever was handy. I have a bit of a reputation in the neighborhood for providing a Christmas radio station. Being near the crest of a bluff, the reach of this little box is remarkably good, spanning the immediate area, neighborhoods downhill from us and even on the ridge across from us. So I feel a bit of pride and an obligation to maintain and improve.

Two Christmases ago I moved from Windows- basically an m3u playlist dragged and dropped onto Winamp and shuffled and looped from December through January. During that time, Winamp needed at least three restarts, and Windows 8 would cough up a hairball and die about once every two weeks. I had grown tired of tuning into the station only to hear dead air and realized it was time to up my tech game. I had this windows laptop around when I got the wild hair to play radio Santa and spent enough time compiling music for this project, let alone tweaking the setup. But I’d had enough.

At first it was a simple alternative. I wanted to use the same machine of limited capabilities, so it had to be very low resource. I installed Ubuntu and booted it straight into the console. I used a simple console player- MP3123- and invoked one command on startup, for MP3123 to play all of the files it found in a certain subdirectory. And it worked pretty well. No dead air. No restarts. But there was zero flexibility. playlist management consisted of adding and deleting files. And while I do have a few radios and even an FM tuner in my stereo, I really wanted to access the station in more modern ways.

Enter DAAP- Digital Audio Access Protocol. It’s most commonly known as the transport protocol used by iTunes. Fortunately, it also has wide platform adoption beyond Apple. What really sold it was finding a Linux daemon called daapd that supports MTP clients. One example of that is my ten-year old Roku Soundbridge, which has been gathering dust in a cabinet for a few years now. Another is an app in the play store. Yet others are a couple of Linux programs. So I could set up a server to make the playlist available via several devices; one of the less mobile ones can be the dedicated radio station device that will output right to the FM transmitter. So many bases covered!

forked-daapd supports these kinds of clients:

DAAP clients, like iTunes or Rhythmbox
Remote clients, like Apple Remote or compatibles for Android/Windows Phone
AirPlay devices, like AirPort Express, Shairport and various AirPlay speakers
Chromecast devices
MPD clients, like mpc (see mpd-clients)
MP3 network stream clients, like VLC and almost any other music player
RSP clients, like Roku Soundbridge

Here is a list of working and non-working DAAP and Remote clients. The list is probably obsolete when you read it 🙂

Client Developer Type Platform Working (vers.)
iTunes Apple DAAP Win, OSX Yes (12.1)
Rhythmbox Gnome DAAP Linux Yes
WinAmp DAAPClient WardFamily DAAP WinAmp Yes
Banshee DAAP Linux/Win/OSX No (2.6.2)
jtunes4 DAAP Java No
Firefly Client (DAAP) Java No
Remote Apple Remote iOS Yes (4.2.1)
Retune SquallyDoc Remote Android Yes (3.5.23)
TunesRemote+ Melloware Remote Android Yes (2.5.3)
Remote for iTunes Hyperfine Remote Android Yes
Remote for Windows Phone Komodex Remote Windows Phone Yes (
TunesRemote SE Remote Java Yes (r108)

I even had the closest I could imagine ME having for a host computer- a fresh install of Ubuntu Server 17.04 on a headless IBM desktop. I had already set up SSH and was working on it remotely to set it up. It was ready to be used for something fun. The only problem was it was in the basement on my bench. I was upstairs in a cast. So however I did this, it had to be completely remotely. A challenge!

The first challenge was how to copy files. I could set up an rsync command to clone the collection over to the remote machine. But I wanted to pick and choose as I went, and a facility for moving things around on the remote machine quickly if needed. So I installed an FTP server. All I had to do was install:

$ sudo apt-get install vsftpd

Installing forked-daapd

If you are the lucky kind, this should get you all the required tools and

sudo apt-get install \
build-essential git autotools-dev autoconf libtool gettext gawk gperf \
antlr3 libantlr3c-dev libconfuse-dev libunistring-dev libsqlite3-dev \
libavcodec-dev libavformat-dev libavfilter-dev libswscale-dev libavutil-dev \
libasound2-dev libmxml-dev libgcrypt11-dev libavahi-client-dev zlib1g-dev \
libevent-dev libplist-dev libsodium-dev libjson-c-dev libwebsockets-dev

Optional packages:

Feature | Configure argument | Packages
Chromecast | --enable-chromecast | libgnutls-dev libprotobuf-c-dev
LastFM | --enable-lastfm | libcurl4-gnutls-dev OR libcurl4-openssl-dev
iTunes XML | --disable-itunes | libplist-dev
Device verification | --disable-verification | libplist-dev libsodium-dev
Live web UI | --with-libwebsockets | libwebsockets-dev
Pulseaudio | --with-pulseaudio | libpulse-dev

After installation, edit the configuration file, /etc/forked-daapd.conf.

Note that ‘sudo make install’ will not install any system files to start the
service after boot, and it will not setup a system user.

forked-daapd will drop privileges to any user you’ll specify in the
configuration file if it’s started as root.

This user must have read permission on your library (you can create a group for this and make the user a member of the group, for instance) and read/write permissions on the database location ($localstatedir/cache/forked-daapd by default).

If your system uses systemd then you might be able to use the service file
included, see forked-daapd.service.

Otherwise you might need an init script to start forked-daapd at boot. A simple init script will do, forked-daapd daemonizes all by itself and creates a pidfile under /var/run. Different distributions have different standards for
init scripts and some do not use init scripts anymore; check the documentation for your distribution.

For dependency-based boot systems, here are the forked-daapd dependencies:
– local filesystems
– network filesystems, if needed in your setup (library on NFS, …)
– networking
– Avahi daemon

The LSB header below sums it up:

# Provides: forked-daapd
# Required-Start: $local_fs $remote_fs $network $time
# Required-Stop: $local_fs $remote_fs $network $time
# Should-Start: avahi
# Should-Stop: avahi
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: DAAP/DACP (iTunes) server, support for AirPlay and Spotify
# Description: forked-daapd is an iTunes-compatible media server for
# sharing your media library over the local network with DAAP
# clients like iTunes. Like iTunes, it can be controlled by
# Apple Remote (and compatibles) and stream music directly to
# AirPlay devices. It also supports streaming to RSP clients
# (Roku devices) and streaming from Spotify.

after starting play, press the “*” button. Options will come up. This works for photos and music


# save new source playlist

#grab date
now=$(date +"%m_%d_%Y")

# check for new items by building new playlist based on date
find /srv/Music/ -iname "*.mp3" > playlist$now.m3u

# shuffle the playlist
shuf playlist$now.m3u -o stationlist.m3u
#reset perms
chmod 777 stationlist.m3u

add a cronjob to to the daapd user:

30 00 * * * /srv/Music/

Make sure the daapd user has access to the cache folder:

chown -R daapd:nogroup /var/cache/forked-daapd/

For this distro, I can just restart Cron and it will pick up the script schedule:

# service crond restart

That’s it! Now just find your server on your daap player and let it play!

This was a fun project, though I have subsequently moved on to another project with more radio station-type automation, but the daap server project saw me through that Christmas season with no hiccups at all.