Forked-daapd
This package replaces mt-daapd
Build
Over the last several releases of Ubuntu, mt-daapd's transcoding has not worked for me out of the box. I had always been able to find a workaround (for example, for 9.04, see this post (http://ubuntuforums.org/showpost.php?p=7341087&postcount=3)); however, 9.10 has me totally stumped.
In searching for a replacement, I came across forked-daapd (http://blog.technologeek.org/2009/06/12/217) (see also this firefly forum post (http://forums.fireflymediaserver.org/viewtopic.php?f=2&t=29772)). It does what mt-daapd does minus the web interface. I never used mt-daapd's web interface, so no loss for me there.
Note: The author has made AMD 64-bit packages available: forked-daapd (http://debian.technologeek.org/forked-daapd/) and antlr3 (http://debian.technologeek.org/antlr/). If you're on i386 like me, keep reading.
Installing forked-daapd was a challenge. Thankfully, the author was kind and patient enough to help me get it up and running. Here's what it took.
- Grab the forked-daapd package:
git clone git://git.debian.org/~jblache/forked-daapd.git
Read the README and INSTALL files so you know what's up. Panic when you read something about antlr3, discover that the stock Ubuntu version is too old, and discover that it has something to do with java. Now relax, I'll walk you through it.
- Make sure you have the other required libraries installed (and -dev variants):
Libraries:
glibc 2.9+ (for signalfd) Avahi client libraries, 0.6.24 minimum sqlite3 ffmpeg confuse libevent 1.4+ libavl MiniXML libflac (optional) taglibc (optional) libplist 0.15+ (optional - iTunes XML support)
- Get antlr3 packages
I first installed the antlr3 packages from the repositories. Then I got the antlr-3.1.3.jar (http://www.antlr.org/download/antlr-3.1.3.jar). Edit /usr/bin/antlr3 and in the CLASSPATH variable replace the path to the antlr-3.1.3.jar you downloaded. Don't worry about the stringtemplate.jar.
- Grab the C libraries for antlr3 at http://antlr.org/download/C (3.1.3). Build and install with the typical
./configure --prefix=/usr ; make ; sudo make install
- Configure and build forked-daapd
Assuming you got the required libraries and antlr3 packages installed, you're ready to configure and build forked-daapd. Enter its directory and run autoreconf -i to build the configure script. I ran the configure script as recommended in the INSTALL:
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-flac --enable-musepack
Your configure options might be different depending on your needs. Run `make` and `sudo make install`.
- Add user daapd
Forked-daapd will run with user daapd. I had to create the user on my system:
sudo useradd -r daapd
I also had to make sure user daapd could read my music library. I added daapd to the group music, which has read access to my library:
sudo usermod -G music daapd groups daapd (That last line just to verify.)
- Point to your library in the conf file
The conf file is /etc/forked-daapd.conf. There's not much to configure, just point to your music library under "Directories to index."
- Create directory for database
The database will live in /var/cache/forked-daapd so create that directory and make daapd the owner:
sudo mkdir /var/cache/forked-daapd sudo chown daapd /var/cache/forked-daapd
- Fire up forked-daapd with:
sudo /usr/sbin/forked-daapd
If you run into issues with your Soundbridge or other device not being able to see the server, check out this post (http://ubuntuforums.org/showpost.php?p=7335637&postcount=7) to learn how to add the daap service to avahi. Mine was a holdover from struggling with mt-daapd.
Startup Script
#! /bin/sh
### BEGIN INIT INFO
# Provides: forked-daapd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start forked-daapd
# Description: Start forked-daapd, a media server using
# the DAAPD protocol
### END INIT INFO
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin
DESC="DAAP server for media sharing"
NAME=forked-daapd
DAEMON=/usr/sbin/$NAME
DAEMON_ARGS=""
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
# Not really necessary, nothing else should depend on this
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
: