mikebrady / shairport-sync

AirPlay and AirPlay 2 audio player
Other
7.3k stars 574 forks source link

Autostart doesn't work #58

Closed DonPavlov closed 9 years ago

DonPavlov commented 9 years ago

I have installed the latest release on my raspbian. If i execute the shairport-sync command, it runs in the background. But it doen't work in the autostartup. If I execute sudo service shairport-sync start, nothing happens. What can i do? I just want it to start on startup. thx.

senthor commented 9 years ago

I have (maybe) a corresponding issue: autostart doesn't work either, but service shairport-sync start corrects the issue. Seems like shairport-sync crashes right at the start, as the corresponding pid to the one saved is not found. I'm currently just staring the service again in /etc/rc.local, and that works fine.

mikebrady commented 9 years ago

Hi there, and thanks for your interest in Shairport Sync. If you followed the instructions to do the full compilation using make, you should follow it with sudo make install to install shairport-sync and also a startup script. (You may have to edit the startup script to point to the correct also device, etc.) Then you can check its status, start or restart it, etc. Here is what happens on my Raspian setup starting from when the sudo make install is complete.

pi@raspberrypi ~ $ service shairport-sync status
[FAIL] shairport-sync is not running ... failed!
pi@raspberrypi ~ $ sudo service shairport-sync status
[FAIL] shairport-sync is not running ... failed!
pi@raspberrypi ~ $ sudo service shairport-sync start
pi@raspberrypi ~ $ sudo service shairport-sync status
[ ok ] shairport-sync is running.
pi@raspberrypi ~ $ 

If you're not getting something like that, then there is something wrong with your setup. Check the log for clues. Below, it's showing that shairport-sync started without incident.

pi@raspberrypi ~ $ tail /var/log/syslog

...
Mar  9 11:02:43 raspberrypi shairport-sync[11508]: startup
...

I hope this helps.

mikebrady commented 9 years ago

Yikes – our posts crossed each other.

mikebrady commented 9 years ago

@senthor, I'd be interested in that phenomenon of apparently crashing at the start. Could you share the startup script and the rc.local entry please? Is it a Raspberry Pi?

senthor commented 9 years ago

Hey, no, I'm using an Atom-based Ubuntu 14.0.4 LTS homeserver. My /etc/init.d/shairport-sync:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          shairport-sync
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Shairport Synchronous AirPlay
# Description:       Implements a synchronous (multi-room-capable) AirPlay receiver
### END INIT INFO

# Author: Mike Brady <mikebrady@eircom.net>
#
# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="AirPlay Synchronous Audio Service"
NAME=shairport-sync
DAEMON=/usr/local/bin/$NAME

# We don't use the DAEMON_ARGS variable here because some of the identifiers may have spaces in them, and so are
# impossible to pass as arguments.

# Instead, we add the arguments directly to the relevant line in the do_start() function below

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.2-14) to ensure that this file is present
# and status_of_proc is working.
. /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
# Uncomment just one of the following start-stop-daemon lines, or comment them all out and add your own.
# In the default script, the first line is uncommented, selecting daemon mode (-d), the default device and software volume control
# BTW, if you're using software volume control, you may have to use alsamixer or similar to set the output device's volume to its maximum level first
# BTW2, you can use alsamixer to find device identifiers (e.g. hw:1) and mixer names (e.g. "Speaker"). No need to change ALSA's defaults.
# BTW3, the argument after -a is simply the name the shairport service will be visible as.
#   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d -a "Zephyr HiFi" || return 2
#   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d -a "Topping TP30 or Griffin iMic on Raspberry Pi" -- -d hw:1 -t hardware -c "PCM" || return 2
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d -a "Zephyr HiFi" -S soxr -- -d hw:0 -t hardware -c "Front" || return 2
# BTW, that "3D Sound" USB soundcard sometimes has the mixer name "Headphone" rather than "Speaker" -- use alsamixer to check.
#   start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d -a "IQaudIO" -- -d hw:1 -t hardware -c "Playback Digital" || return 2
# BTW, newer versions of IQaudIO have a different mixer name -- use alsamixer to check.
    # 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.
}

#
# 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

And in /etc/rc.local it's just

service shairport-sync start

Output if not using above and manually starting:

$ sudo service shairport-sync status
 * shairport-sync is not running
$ sudo service shairport-sync start
Process 1430 died: No such process; trying to remove PID file. (/var/run/shairport-sync.pid)
DonPavlov commented 9 years ago

Well in my case service shairport-sync start does nothing. Even the status command does not even show a failed or anything. Just nothing.

mikebrady commented 9 years ago

Thanks for your replies. I wonder if the init script is asking shairport-sync to start up too early in the boot sequence. To explore this, could I ask you to make two edits to the /etc/init.d/shairport-sync file please?

    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d -a "Zephyr HiFi" -S soxr -- -d hw:0 -t hardware -c "Front" || return 2

to read:

    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- -d -v -a "Zephyr HiFi" -S soxr -- -d hw:0 -t hardware -c "Front" || return 2

(You can see that the difference is to add in the -v option.)

# Required-Start:    $remote_fs $syslog

to read:

# Required-Start:    $localfs $remote_fs $syslog

This may fix the problem, but in any case, I'd be grateful if you'd let me know what, if anything, happens, or what might be reported in the /var/log/syslog file, or equivalent.

senthor commented 9 years ago

After just editing in the -v I get the following message in syslog: Mar 11 21:18:04 Zephyr shairport-sync[1557]: Failed to attach mixer The same happens with altered Required-Start.

mikebrady commented 9 years ago

Very interesting. It looks like the ALSA subsystem is not ready – the audio mixer isn't available – by the time the init script runs. To check this, could you do a further edit to add in a delay please? In the init script, put a command to sleep for 10 seconds just before the start command is issued. That is, insert the command above the line that reads:

# Uncomment just one of the following start-stop-daemon lines, or comment them all out and add your own.

so that is reads:

         sleep 10
# Uncomment just one of the following start-stop-daemon lines, or comment them all out and add your own.

If this makes it work properly, then my idea that the init script needs to be called later would be vindicated.

senthor commented 9 years ago

* shairport-sync is running Success! :)

mikebrady commented 9 years ago

Excellent! It might be worth experimenting with the delay, to make it as short as possible, but it does point to a delay in the ALSA system being ready. If you do experiment, could you let me know what delay you settle on?

senthor commented 9 years ago

I've settled now with sleep 2sleep 1was too short.

senthor commented 9 years ago

The only sound-related entry in syslog that I could find that happened after shairport-sync start without sleep and now happens right before is: Mar 11 22:40:12 Zephyr kernel: [ 7.676680] snd_hda_intel 0000:00:1b.0: irq 108 for MSI/MSI-X

mikebrady commented 9 years ago

Thanks. I can only guess that it's a message indicating that the sound card is just hooked up.

DonPavlov commented 9 years ago

Ok. I finally configured my init.d file right and added a sleep 3. Now it works for me.

mikebrady commented 9 years ago

Thanks to both of you. So, the take-away message is that on some systems the init script starts Shairport Sync before the audio system is ready. The fix is to insert a delay into the init script. Three seconds looks good.

senthor commented 9 years ago

@dehein: Just in case, because I was wondering why sleep worked but manually starting the service didn't, did you sudo? sudo service shairport-sync start In case anybody else wonders ;-)

fidoboy commented 9 years ago

I'm having the same problem. sudo service shairport-sync start or service shairport-sync status returns nothing. It only works for me if calling directly with shairport-sync -a "airpi". I've also tried adding the sleep into the init script but the service isn't started.

What else could I try?

mikebrady commented 9 years ago

Thanks for the report . Is this on a Raspberry Pi? If so, what model and what distro are you using?

Is there anything from shairport-sync in the logfile?

fidoboy commented 9 years ago

I'm sorry Mike, it was my fault. I changed the NAME var in the init script (I was thinking that it was to change the displayed name) and this caused the problem. Now I've edited the start-stop-daemon line to add a new parameter with my custom name.

So, great script! It works flawlessly for the moment. My only complaint is about the white noise coming from speakers when the streaming starts, but it's not really very important. :smile:

mikebrady commented 9 years ago

Great. Wondering now about the white noise. Are you using the built-in audio that's routed to its headphone jack?

fidoboy commented 9 years ago

Yes

mikebrady commented 9 years ago

Fair enough – that would account for the white noise, I'd say.

fidoboy commented 9 years ago

It's very noticeable for a second or may be less, when streaming starts, but then it disappears and sound quality is ok, no noticeable white noise on background when playing. I've read about using a external USB sound card, but i believe that for my requirements the current quality is more than enough.

mikebrady commented 9 years ago

Thanks. Yes, that's been my experience with it too.

mbifulco commented 9 years ago

Hi @mikebrady - I'm also having a very similar experience to the folks noted above. I did have a fully functioning Pi B+ with a HifiBerry audio card until recently, when I updated the source code for shairport-sync on my device with a git fetch/pull.

I'm suspicious that what's happened is my /etc/init.d/shairport-sync file may not be compatible with the new version of the source code, since you noted in your documentation that the file won't be overwritten by your code. What's the best way to check what's going on? I added the

sleep 10

line where needed, and modified the

# Required-Start:    $localfs $remote_fs $syslog

line, to no avail.

mikebrady commented 9 years ago

Hi Mike. I can't, offhand, think of any changes that would make the /etc/init.d/shairport-sync invalid. A couple of questions: did you update the operating system too and/or use rpi-update? The reason I ask is that these may cause the audio device to move or to get a different device name or even to disappear!

So, I have an idea: use alsamixer to check that the HifiBerry is (1) there, (2) hasn't moved, (3) has the same name for its volume control mixer.

I do not have a HiBerry, but i do have a PiDac, and it disappeared after an OS upgrade – the OS started supporting "Device Trees" and I had to select an appropriate one and add it to the configuration.

mbifulco commented 9 years ago

Thanks for the response - I did update the os with

sudo apt-get update
sudo apt-get upgrade

After going back and looking at alsamixer, it appears that the problem was that the name of the volume channel on my HifiBerry changed with a recent software update - from "PCM" to "Digital". Changing that and restarting the service seems to have done the trick!

I'm a bit surprised that the verbose settings for shairport-sync weren't helpful in this case. I'd at least expect the log to show what was crashing out the service.

Thanks for your support! This is a great project, and I'm happy to be able to use it, even when little niggling things like this come up.

mikebrady commented 9 years ago

Thanks Mike. I'll think about adding some extra diagnostics. I did think Shairport Sync would report that it couldn't find the mixer, but I'll check. Many thanks for your support!

poot17 commented 9 years ago

Hi Mike, I am experiencing the same "auto-start not working" issue using shairport-sync on Raspberry Pi 2 Model B, however I am using systemd instead of V. Would it still be advisable to put a delay in the startup of the application? If so, how would I apply it as I do not have an /init.d/shairport-sync file. Many thanks for your development work. -Matthew

poot17 commented 8 years ago

Problem solved! Seems I had the call to start shairport-sync incorrectly placed in /etc/rc.local. For reference (for systemd users), you need to have "service shairport-sync start" before "exit 0", which makes sense when you think about it, but I wasn't looking there. It now starts up at boot every time. Now just to figure out where in the build process this happened...

mikebrady commented 8 years ago

Thanks for the update. If it works, it works! However, in general if you're using a systemd-based system, like Raspian or Debian Jessie, then the --with-systemd configuration option will enable the make install step to install the correct startup resources and scripts, although it doesn't activate them. To activate them, all you should need to do then is to enable the shairport-sync service and, if you wish, to start it there and then with the appropriate systemctl commands. You should not need to put anything in the /etc/rc.local file.

benjaminfrombe commented 8 years ago

I think there is still something wrong with the startup script: even if I uncomment the sleep command and start it manually, it doesn't execute the sleep, nor does it do any other command. (tried to add some echo commands to see if they are printed when starting the service) It seems like the script exits before those lines, somewhere in the /lib/lsb/init-functions included file ... So everything after this line gets ignored ...

so workaround for me was to also put in it rc.local ... So all 'uncomment this line if ...' are useless.

using RPI model 2B (debian - jessie)

mikebrady commented 8 years ago

Thanks for the report. I am guessing you're talking about a System V startup script in a systemd system (Jessie). I think it would be worth checking the configuration options you used to make sure you selected --with-systemd and not --with-systemv.