Hi, first, thanks for such an incredibly useful piece of software.
I'm hoping to use a remote control to pause / play / skip tracks using my Raspberry Pi (it's not always easy for me to get out a phone to do this). I read through the old issue on this topic, but couldn't follow what the ultimate result was. Are there command line controls for pausing / skipping tracks?
Thanks!
Thanks for your kind words!
As regards the remote control idea, it has gone through a number of phases. Ultimately, it became clear – to me at least – that it would require some work in the Zeroconf / Bonjour area which could be implemented using Avahi, but not with tinysvcmdns, so I was rather happy to drop the idea.
Instead, the information needed to identify the source is exported in the metadata stream. Conceivably, therefore, one could write an app that received metadata from Shairport Sync and used it in conjunction with some Avahi services to locate the audio source and then send remote control commands to it.
It may be that someone has already done this, BTW – if so, please forgive my ignorance.
On a slightly more practical point, the effort that can be put into something like Shairport Sync is limited, and it still contains bugs, so it's probably better to concentrate on its core functions. That's my 2¢ anyway.
Thanks for the clarification. I'm glad the app works and it makes things so much nicer for me without an Apple TV. I was mostly just checking in to see what the status was, not making a feature request. Thanks again for your efforts here and for sharing.
I'm working on something like this (in node) for quite some time ;) (but I really don't have spare time lately)
As far as I rembember @luckydonald did (or wanted to do) it in https://github.com/luckydonald/shairport-decoder
I'm closing this issue, if that's okay. Please feel free to reopen it if there are any developments.
Does anyone have working example of this?
Will it be possible to output the client name and the received RTSP headers? We could then use a simple bash script to lookup dacp ip and port via avahi-browse and send commands to the dacp address using curl.
Right now I am using tcpdump to sniff traffic and extract the DACP-ID and Active-Remote headers. Then do an avahi lookup against _dacp._tcp and filter the DACP-ID then curl the control I want. It works but it's very hacky. Would appreciate a cleaner approach.
Thanks for the post. There's a D-Bus interface now in Shairport Sync that does most of this for you, including sending DACP commands to the player. And there's an MQTT interface in development.
Also, if you you at the Shairport Sync metadata interface (see here for a reader), it will give you the DACP-ID and port number of a playing session.
Thanks for the awesome piece of software!
Is there any documentation for utilizing the D-Bus interface? Or should I just wait for the MQTT interface to be released?
The problem with metadata-reader is that it outputs the daid and acre only on connection setup. There isn't a way to query these values on demand.
No documentation yet, I'm afraid. But if you look at the sample bus commands in the documents folder and then if you look at the org.gnome.ShairportSync.xml file (use a web browser), you should be able to see what commands and properties are available and how to call them from a script.
I just tried running one of the commands
dbus-send --system --print-reply --type=method_call --dest=org.gnome.ShairportSync '/org/gnome/ShairportSync' org.gnome.ShairportSync.RemoteControl.VolumeUp
and got hit by this
Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.ShairportSync was not provided by any .service files
I am guessing there is a problem with the path. Running this on headless raspbian btw.
Thanks. There are a few things, and sorry there's no documentation yet. You must build Shairport Sync with the extra configuration flag --with-dbus-interface and you must fully install it as a system service and restart it as given in the README.md. It will run as a system service and will run under user and group shairport-sync. Only then will the D-Bus interface be provided -- the restrictions are due to security concerns in the D-Bus system. It's awkward to get working, I guess, but when it works, it's a charm.
So I rebuilt --with-dbus-interface, added dbus options to the config and voila! It works perfectly! Thank you so much!
Great. If you could list the steps, from your experience, it would be very useful for me making up a guide -- sometime I forget something important because I've been using it for so long...
For anyone who comes looking for this. I basically ran the following commands.
apt install -y build-essential git xmltoman autoconf automake libtool libdaemon-dev libpopt-dev libconfig-dev libasound2-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev libsndfile1-dev libglib2.0-dev
git clone https://github.com/mikebrady/shairport-sync.git
cd shairport-sync/
autoreconf -i -f
./configure --sysconfdir=/etc --with-alsa --with-pipe --with-stdout --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-convolution --with-dbus-interface --with-systemd
make
make install
Then uncommented the line dbus_service_bus = "system"; in /etc/shairport-sync.conf followed by a systemctl restart shairport-sync
Afterwards, I setup a wrapper script
cat > /usr/local/bin/airplay-remote << 'EOF'
dbus-send --system --print-reply --type=method_call --dest=org.gnome.ShairportSync '/org/gnome/ShairportSync' org.gnome.ShairportSync.RemoteControl.$1
EOF
chmod +x /usr/local/bin/airplay-remote
Now I can use airplay-remote Pause/Play/VolumeUp/VolumeDown to control playback.
Super, thanks. I'm actually going to reopen this issue, make it easier for people to find.
Glad I could contribute back. Cheers!
This also fixes #5
Thanks!
Would be nice to be able to use the dbus-interface on a non-systemd system. Is that possible?
Haven't looked, TBH. What system are you thinking of?
I'm using it on FreeBSD. But systemd isn't the issue, I misunderstood. The issue is that the dir it's installing the shairport-sync-dbus.conf file in doesn't exist:
[ -e $(DESTDIR)$(sysconfdir)/dbus-1/system.d ] || mkdir -p $(DESTDIR)$(sysconfdir)/dbus-1/system.d
I can send a pull request if you like.
Also, there's another issue in that the shairport-daemon runs as nobody by default currently, instead of shairport-sync. We could create a shairport-sync user and run under that. But we also currently allow overriding the user, so we would also have to stop allowing that. Thoughts on best way to proceed?
Let me have a look.
So, it seems that the D-Bus installation must go into /etc and never /usr/local/etc, so I can easily fix that... Let me check the user issue.
That doesn't seem right. I have:
-rw-r--r-- 1 root wheel 646 Mar 18 09:47 /usr/local/etc/dbus-1/system.d/shairport-sync-dbus.conf
and it seems to be working fine.
Hmm -- $(DESTDIR)$(sysconfdir) should resolve to /usr/local/etc by default.
Anyway, I was just checking on a FreeBSD system. Everything seems to work properly following the standard installation but adding --with-dbus-interface:
[mike@FreeBSD /usr/home/mike/shairport-sync]$ ps aux | grep shai
shairport-sync 2973 0.0 0.4 136648 14984 - S 14:36 0:00.04 /usr/local/bin/shairport-sync -d
mike 2975 0.0 0.1 14908 2688 0 S+ 14:37 0:00.00 grep shai
[mike@FreeBSD /usr/home/mike/shairport-sync]$ dbus-send --print-reply --system --dest=org.gnome.ShairportSync /org/gnome/ShairportSync org.freedesktop.DBus.Properties.Set string:org.gnome.ShairportSync.Diagnostics string:Verbosity variant:int32:1
method return time=1552919845.554474 sender=:1.54 -> destination=:1.56 serial=10 reply_serial=2
[mike@FreeBSD /usr/home/mike/shairport-sync]$ uname -a
FreeBSD FreeBSD 11.1-RELEASE-p15 FreeBSD 11.1-RELEASE-p15 #0: Thu Sep 27 06:05:25 UTC 2018 [email protected]:/usr/obj/usr/src/sys/GENERIC amd64
[mike@FreeBSD /usr/home/mike/shairport-sync]$
So, the shairport-sync user is automatically defined and the D-Bus commands are working... Maybe I'm missing something...
Yes, $(DESTDIR)$(sysconfdir) exists and is /usr/local/etc/ and the dbus-1 dir below it exists, but the system.d dir below that does not necessarily exist unless something else has created it. You likely have it because of that. In my case, I'm building in a special jail which has only the build dependencies installed and so the system.d dir does not exist, hence adding the
[ -e $(DESTDIR)$(sysconfdir)/dbus-1/system.d ] || mkdir -p $(DESTDIR)$(sysconfdir)/dbus-1/system.d
line to the Makefile.am before shairport-sync-dbus.conf is installed.
Aagh -- sorry for being so dense; I just didn't read your suggested addition properly. I'll certainly add that in.
It looks like the part of the script that defines the shairport-sync user and group is after the part that attempts to install the D-Bus policies, so make the installer was failing before defining the user and group. Could that account for the rest of your issues?
Thanks!
The user issue is likely a separate one. I'm packaging shairport-sync via the FreeBSD port which doesn't currently create a user, although it could be made to do so fairly easily.
But, it's a long story.
My goal is to have obs-studio capture sound from shairport-sync. But obs-studio doesn't support sndio, only pulseaudio. The pulseaudio port/package currently doesn't create a user or have an init script, so I just run pulseaudio as my user (I could write a script, but just running it as myself is easier for now).
So, I'm using shairport-sync to send data to a pulseaudio server running as my own user, which seemed to require that I run shairport-sync as my user as well (I forget the details here) rather than the default nobody user (and presumably running shairport-sync as the shairport-sync user wouldn't work either).
Right now this is all working because of:
shairport-sync-dbus.confIt seems like even if I were using the standard installation you mention above, I would still have this issue, because I would still need to change the user in the shairport-sync-dbus.conf file. I don't really know enough about dbus to know if it could be possible to change the user at run time. (Changing it at build time would be insufficient because the script would still allow changing it at run time. I guess that could change, but it seems a shame to hard code a simple thing like a username.)
(For what it's worth, the port/package allow users to run pkg install shairport-sync and get working software without having to compile.)
Interesting project. Does OBS Studio allow you to take audio from a Unix pipe, I wonder?
I'm no D-Bus expert myself, but the following policy document would allow any user to run a Shairport Sync DBus server:
<!-- initial version, based on /etc/dbus-1/system.d/avahi-dbus.conf, with thanks -->
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<!-- Allow anyone to own and invoke methods on Shairport Sync server -->
<policy context="default">
<allow own="org.gnome.ShairportSync"/>
<allow send_destination="org.gnome.ShairportSync"/>
<allow receive_sender="org.gnome.ShairportSync"/>
</policy>
</busconfig>
Not sure it's what you're looking for, TBH...
I don't think OBS supports anything except PulseAudio. I will have to re-try and see what happens when shairport-sync is running as a different user than pulseaudio, I think that will help clarify the need. Are you saying that config file would replace the one that comes with shairport-sync or be one to add so that the default one can be used and then be overridden?
Fair enough. Yes, the policy document above would completely replace the one that comes with shairport-sync. (I've found and fixed one or two errors with how Shairport Sync demonises and pushed them out in the development branch. They would manifest by e.g. $ sudo service shairport_sync stop not working.)
Closing this inactive issue. Please open a new one if necessary.