Dacp / daapd / iTunes support

would be nice to have support for iTunes or the daapd/dacp protocol. I currently run forked-daapd (http://ejurgensen.github.io/forked-daapd/) as my music server which is very nice, especially with airplay. It also supports spotify.

As reference:

https://github.com/home-assistant/home-assistant/issues/423

This deservers more love - I’d love to see this implemented as I’ve jumped through lots of hoops with various music ‘hosts’ that are becoming outdated without active development but forked-daapd has been a great solution for having a library I can simply add playlists/content to and easily control from my iPhone.

I’m working on a little project right now that may help with this, check out forked-daapd-api.

Don’t try to use it yet, it still a work in progress

Basically, it is a little Java app that runs on the same server as forked-daap. It provides a simple REST API and makes the DACP calls that other remotes (like iPhones) make to forked-daapd. Since Home Assistant supports REST calls and cURL, I think it will interface nicely.

I plan on supporting:

  • Player status (get/play/pause)
  • Speaker controls (list, set active)
  • Volume controls (get/set master volume, get/set speaker volume, fade in/out speaker volume)
  • Playlists (list/set)

Let me know if you have any feedback or requests that will make this more usable in Home Assistant. I’m not currently using Home Assistant but I plan on setting it up and interfacing with forked-daapd in the near future.

1 Like

This seems like a great idea!

I’m looking for a solution that would allow HA to interface with my Airport Express :slight_smile:

Have you had any progress with this? I’d be very keen to add this to my system as I’m now using AirPlay for all of my multi-room audio (Shairport-Sync on RPIs eveywhere) and Home Assistant is the only let down so far.

you can use mpd to control forked-daapd…

I’m already using MPD (via curl commands) from Home Assistant to play and stop a radio stream, but have personally found it difficult to find a good source to learn more about doing this, and expand my use to get status feedback and allow independent control of more endpoints (like you get with the Apple Remote app) through Home Assistant.

I agree it could be more comfortable. I am using python scripts to set individual speakers volumes: Those scripts I then call from home-assistant. Its not beautiful but works.

import sys
from mpd import MPDClient

client = MPDClient()
client.connect('localhost', 6600)
client.outputvolume(int(sys.argv[1]), int(sys.argv[2]))
client.disconnect()

I did get this to a point where I could control master and individual speaker volumes and added a simple frontend (/remote) so that much should work.

However, I discovered Snapcast and decided to use that instead. My setup is similar to yours, a number of Raspberry Pis each driving a set up speakers.

Some Pros:

  • Faster response time
  • Excellent support in Home Assistant (although is broken currently, a fix has already been merged in dev)
  • Excellent support for streams from different sources
  • Simpler to setup/maintain

Some Cons:

  • Not part of Apple ecosystem
  • Manual control only through Android App or HA (a Perl webapp exists, took a bit to setup) so overall less support for remote controls

My main goal was to play in-sync music in multiple rooms from Spotify and interrupt it to make TTS announcements via HA. I didn’t need a big library management remote (don’t have a big library of local files/playlists that I want to play). Snapcast is definitely a better fit for those requirements.

Anyway, I won’t be putting much time into the forked-daapd-api but feel free to ask if you decide to use it and have any trouble with setup

Hey!

So if I’m understanding this right, forked-daapd is used to send Spotify audio to an Airport Express.
To control forked-daapd I have to use Python scripts as a work around for lack of HA support - is that correct?

partly correct as some aspects of forked-daapd can be controlled directly through the home-assistant mpd binding. since forked-daapd can be controlled via the mpd protocol for which home-assistant has support.

however changing individual speaker volume is only possible via python or shell scripts (or of course through one of the many remote apps that can control forked-daapd)

and with regards to the spotify integration… forked-daapd can access spotify saved songs and playlists. they show up as if they were in your local library.

I additionally however use librespot which allows me to select it in the spotify app as a spotify-connect speaker. librespot then outputs to a named pip which is read by forked-daapd… But that is only so I can use spotifys radio functionality or allow guests to play spotify from their phone to the whole house…

Ok I may try that. My goal is to have that setup. That way I think I can achieve the following:

  • librespot plays Spotify and forked-daapd autoconnects to Airport Express (no need to select manually).
  • Home Assistant can control librespot via Spotify Connect component (play/pause when leaving/entering the house, for example).
  • Either my iPhone or iPad (same account) can control or select the music librespot plays via Spotify Connect.

Is that right?

Thats possible . I have it setup this way.

thats my /etc/systemd/system/spotify-connect.service

[Unit]
Description=Spotify Connect
After=network-online.target
[Service]
Type=idle
User=pi
ExecStart=/home/pi/librespot --backend pipe --device /home/pi/music/spotify -n spotifyConnect --cache /tmp > /dev/null 2>&1
Restart=always
RestartSec=10
StartLimitInterval=30
StartLimitBurst=20
[Install]
WantedBy=multi-user.target

The important part is the --backend pipe --device /home/pi/music/spotify part which tells Spotify connect to use a named pipe as output device. This named pipe has to be created before and of course should be located inside the library that forked-daapd is indexing.

if you include

        # Watch named pipes in the library for data and autostart playback when
        # there is data to be read. To exclude specific pipes from watching,
        # consider using the above _ignore options.
        pipe_autostart = true

in /etc/forked-daapd.conf then forked-daapd will automatically start the playback when librespot fills the pipe (that is when you select librespot in spotify as an output.

You can use whatever Remote app to select the speakers forked-daapd will stream to or you can use mpd to do so via a shell script.

I actually configured switches in home-assistant for that purpose:

  - platform: command_line
    switches:
        airplay_loop:
        command_on: "/usr/bin/mpc -h 192.168.178.94 enable 3243"
        command_off: "/usr/bin/mpc -h 192.168.178.94 disable 3243"
        command_state: "/usr/bin/mpc -h 192.168.178.94 outputs | grep Bad"
        value_template: '{{ value == "Output 3243 (Bad) is enabled" }}

As you probably can guess you can get the speaker ids by using /usr/bin/mpc outputs

hope this helps.

1 Like

Thanks so much! I will work on that this weekend.

Okay wow. This was so much easier than I thought it was! Took me like an hour.

Thanks for your tips man! :slight_smile:

In case it helps anyone else, a dummies guide:

  • Install raspotify (wrapper) on the pi to make it easy on yourself: https://github.com/dtcooper/raspotify
  • Create the pipe. I did mkfifo /opt/music/spotify. This is the --device.
  • Make sure the pipe and music dir is rw for raspotify
  • Add options in /etc/default/raspotify, remove --backend alsa from its systemd config
  • Install forked-daapd:
  1. Add this line to /etc/apt/sources.list:
    deb http://www.gyfgafguf.dk/raspbian jessie/armhf/
  2. Run sudo apt-get update and then sudo apt-get install forked-daapd
  • Install mpc
  • Edit /etc/forked-daapd.conf:
  1. pipe_autostart = true
  2. directories = { "/opt/music" }

Then you just use mpc to turn on the speakers. Super easy.

1 Like

@snizzleorg Do you only ever use your speaker with one account?

I would like to be able to share the speaker between me and my wife. She has her own Spotify Premium account.

I am thinking of starting up two librespot instances and pointing them to the same pipe (if this is possible). When my wife selects her speaker ‘chimpyWife_Speaker’, the Spotify HA component can trigger an automation on ‘playing’ and if source = ‘chimpyWife_Speaker’. The automation would pause my stream (if ‘playing’ to ‘chimpy_Speaker’) thus avoiding the two streams from overlapping.

Another automation would take of the other way around, when she is playing something and I wish to use the speaker.

edit

Just checked and named pipes can accept multiple inputs. Sweet. Time to test.

I think it works with multiple accounts when you do not specify the account while running librespot.

I have to try…

Yeah you can put in discovery mode but that’s not an acceptable solution to me because the Source in Hass eventually disappears whereas when you’re logged in it remains there permanently, even when it’s not locally available.