diff --git a/README.md b/README.md index c4bbc966..f3a3e95b 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ Please follow this [guide](doc/build.md) to build Snapcast for * [macOS](doc/build.md#macos-native) * [Android](doc/build.md#android-cross-compile) * [OpenWrt](doc/build.md#openwrt-cross-compile) +* [Buildroot](doc/build.md#buildroot-cross-compile) + * [Raspberry Pi](doc/build.md#raspberry-pi-cross-compile) ###Install debian packages Download the debian package for your CPU architecture from the [latest release page](https://github.com/badaix/snapcast/releases/latest), e.g. for Raspberry pi `snapclient_0.x.x_armhf.deb` @@ -99,6 +101,10 @@ There is also an unofficial WebApp from @atoomic [atoomic/snapcast-volume-ui](ht This app list all clients connected to a server and allow to control individualy the volume of each client. Once installed, you can use any mobile device, laptop, desktop, or browser. +There is also an [unofficial FHEM module](https://forum.fhem.de/index.php/topic,62389.0.html) from @unimatrix27 which integrates a snapcast controller in to the [FHEM](https://fhem.de/fhem.html) home automation system. + +There is a [snapcast component for Home Assistant](https://home-assistant.io/components/media_player.snapcast/) which integrates a snapcast controller in to the [Home Assistant](https://home-assistant.io/) home automation system. + Setup of audio players/server ----------------------------- Snapcast can be used with a number of different audio players and servers, and so it can be integrated into your favorite audio-player solution and make it synced-multiroom capable. diff --git a/buildroot/Config.in b/buildroot/Config.in new file mode 100644 index 00000000..61d9d1b9 --- /dev/null +++ b/buildroot/Config.in @@ -0,0 +1 @@ +source "$BR2_EXTERNAL_SNAPCAST_PATH/package/snapcast/Config.in" diff --git a/buildroot/configs/snapcast_defconfig b/buildroot/configs/snapcast_defconfig new file mode 100644 index 00000000..cc91640b --- /dev/null +++ b/buildroot/configs/snapcast_defconfig @@ -0,0 +1,40 @@ +# Snapcast Packages +BR2_GCC_VERSION_4_9_X=y +BR2_GCC_VERSION="4.9.4" +BR2_TOOLCHAIN_GCC_AT_LEAST="4.9" +BR2_TOOLCHAIN_BUILDROOT_GLIBC=y +BR2_PACKAGE_DBUS=y +BR2_PACKAGE_EXPAT=y +BR2_PACKAGE_LIBDAEMON=y +BR2_PACKAGE_AVAHI=y +BR2_PACKAGE_AVAHI_AUTOIPD=y +BR2_PACKAGE_AVAHI_DAEMON=y +BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y +BR2_PACKAGE_ALSA_LIB=y +BR2_PACKAGE_ALSA_LIB_DEVDIR="/dev/snd" +BR2_PACKAGE_ALSA_LIB_PCM_PLUGINS="all" +BR2_PACKAGE_ALSA_LIB_CTL_PLUGINS="all" +BR2_PACKAGE_ALSA_LIB_ALOAD=y +BR2_PACKAGE_ALSA_LIB_MIXER=y +BR2_PACKAGE_ALSA_LIB_PCM=y +BR2_PACKAGE_ALSA_LIB_RAWMIDI=y +BR2_PACKAGE_ALSA_LIB_HWDEP=y +BR2_PACKAGE_ALSA_LIB_SEQ=y +BR2_PACKAGE_ALSA_LIB_ALISP=y +BR2_PACKAGE_ALSA_LIB_OLD_SYMBOLS=y +BR2_PACKAGE_ALSA_UTILS=y +BR2_PACKAGE_ALSA_UTILS_ALSACONF=y +BR2_PACKAGE_ALSA_UTILS_ALSACTL=y +BR2_PACKAGE_ALSA_UTILS_AMIXER=y +BR2_PACKAGE_ALSA_UTILS_APLAY=y +BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y +BR2_PACKAGE_LIBCURL=y +BR2_PACKAGE_LIBAO=y +BR2_PACKAGE_LIBVORBIS=y +BR2_PACKAGE_VORBIS_TOOLS=y +BR2_PACKAGE_FLAC=y +BR2_PACKAGE_LIBOGG=y +BR2_PACKAGE_TREMOR=y +BR2_PACKAGE_SNAPCAST=y + +# Other Packages diff --git a/buildroot/external.desc b/buildroot/external.desc new file mode 100644 index 00000000..ac3dd844 --- /dev/null +++ b/buildroot/external.desc @@ -0,0 +1 @@ +name: SNAPCAST diff --git a/buildroot/external.mk b/buildroot/external.mk new file mode 100644 index 00000000..433f339f --- /dev/null +++ b/buildroot/external.mk @@ -0,0 +1 @@ +include $(sort $(wildcard $(BR2_EXTERNAL_SNAPCAST_PATH)/package/*/*.mk)) diff --git a/buildroot/package/snapcast/Config.in b/buildroot/package/snapcast/Config.in new file mode 100644 index 00000000..f9201e0a --- /dev/null +++ b/buildroot/package/snapcast/Config.in @@ -0,0 +1,4 @@ +config BR2_PACKAGE_SNAPCAST + bool "snapcast" + help + Synchronous multi-room audio player diff --git a/buildroot/package/snapcast/S99snapclient b/buildroot/package/snapcast/S99snapclient new file mode 100644 index 00000000..e7c77a8b --- /dev/null +++ b/buildroot/package/snapcast/S99snapclient @@ -0,0 +1,35 @@ +#! /bin/sh + +start() { + echo -n "Starting snapclient: " + start-stop-daemon -S -q -b -x snapclient + [ $? = 0 ] && echo "OK" || echo "FAIL" +} + +stop() { + echo -n "Stopping snapclient: " + start-stop-daemon -K -q -x snapclient + [ $? = 0 ] && echo "OK" || echo "FAIL" +} + +restart() { + stop + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|reload) + restart + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 +esac + +exit $? diff --git a/buildroot/package/snapcast/snapcast.mk b/buildroot/package/snapcast/snapcast.mk new file mode 100644 index 00000000..617ad218 --- /dev/null +++ b/buildroot/package/snapcast/snapcast.mk @@ -0,0 +1,32 @@ +################################################################################ +# +# snapcast +# +################################################################################ + +SNAPCAST_VERSION = master +SNAPCAST_SITE = https://github.com/badaix/snapcast +SNAPCAST_SITE_METHOD = git +SNAPCAST_DEPENDENCIES = libogg alsa-lib # libstdcpp libavahi-client libatomic libflac libvorbisidec +SNAPCAST_LICENSE = GPLv3 +SNAPCAST_LICENSE_FILES = COPYING + +# http://lists.busybox.net/pipermail/buildroot/2013-March/069811.html +define SNAPCAST_EXTRACT_CMDS + rm -rf $(@D) + (git clone --depth 1 $(SNAPCAST_SITE) $(@D) && \ + cd $(@D)/externals && \ + git submodule update --init --recursive) + touch $(@D)/.stamp_downloaded +endef + +define SNAPCAST_BUILD_CMDS + $(TARGET_CONFIGURE_OPTS) $(MAKE) -C $(@D)/client TARGET=BUILDROOT +endef + +define SNAPCAST_INSTALL_TARGET_CMDS + $(INSTALL) -m 0755 -D $(@D)/client/snapclient $(TARGET_DIR)/usr/sbin/snapclient + $(INSTALL) -m 0755 -D $(SNAPCAST_PKGDIR)/S99snapclient $(TARGET_DIR)/etc/init.d/S99snapclient +endef + +$(eval $(generic-package)) diff --git a/client/Makefile b/client/Makefile index d663a3fb..e9fd1939 100644 --- a/client/Makefile +++ b/client/Makefile @@ -36,6 +36,12 @@ CXXFLAGS += -pthread -DNO_CPP11_STRING -DHAS_TREMOR -DHAS_ALSA -DHAS_AVAHI -DHAS LDFLAGS = -lasound -lvorbisidec -logg -lFLAC -lavahi-client -lavahi-common -latomic OBJ += player/alsaPlayer.o browseZeroConf/browseAvahi.o +else ifeq ($(TARGET), BUILDROOT) + +CXXFLAGS += -pthread -DNO_CPP11_STRING -DHAS_TREMOR -DHAS_ALSA -DHAS_AVAHI -DHAS_DAEMON +LDFLAGS += -lasound -lvorbisidec -logg -lFLAC -lavahi-client -lavahi-common -latomic +OBJ += player/alsaPlayer.o browseZeroConf/browseAvahi.o + else ifeq ($(TARGET), MACOS) CXX = g++ @@ -116,7 +122,7 @@ installfiles: installsystemd: @echo using systemd; \ cp debian/$(BIN).service /lib/systemd/system/$(BIN).service; \ - cp debian/$(BIN).default /etc/default/$(BIN); \ + cp -n debian/$(BIN).default /etc/default/$(BIN); \ systemctl daemon-reload; \ systemctl enable $(BIN); \ systemctl start $(BIN); \ @@ -124,7 +130,7 @@ installsystemd: installsysv: @echo using sysv; \ cp debian/$(BIN).init /etc/init.d/$(BIN); \ - cp debian/$(BIN).default /etc/default/$(BIN); \ + cp -n debian/$(BIN).default /etc/default/$(BIN); \ update-rc.d $(BIN) defaults; \ /etc/init.d/$(BIN) start; \ diff --git a/client/debian/snapclient.service b/client/debian/snapclient.service index 68825c54..bdeb35a3 100644 --- a/client/debian/snapclient.service +++ b/client/debian/snapclient.service @@ -1,12 +1,14 @@ [Unit] Description=Snapcast client -After=network.target +After=network-online.target sound.target +Requires=network-online.target [Service] EnvironmentFile=-/etc/default/snapclient Type=forking -ExecStart=/usr/bin/snapclient $SNAPCLIENT_OPTS -PIDFile=/var/run/snapclient/pid +ExecStart=/usr/sbin/snapclient $SNAPCLIENT_OPTS +PIDFile=/var/run/snapclient.pid +Restart=always [Install] WantedBy=multi-user.target diff --git a/doc/build.md b/doc/build.md index 9395f113..fc2b06e2 100644 --- a/doc/build.md +++ b/doc/build.md @@ -200,3 +200,33 @@ Build Snapcast: $ make package/sxx/snapcast/compile The packaged `ipk` files are in `/bin/ar71xx/packages/base/snap[client|server]_x.x.x_ar71xx.ipk` + +##Buildroot (Cross compile) +This example will show you how to add snapcast to [Buildroot](https://buildroot.org/). + +###Buildroot setup +Buildroot recommends [keeping customizations outside of the main Buildroot directory](https://buildroot.org/downloads/manual/manual.html#outside-br-custom) which is what this example will walk through. + +Clone Buildroot to some place in your home directory (``): + + $ BUILDROOT_VERSION=2016.11.2 + $ git clone --branch $BUILDROOT_VERSION --depth=1 git://git.buildroot.net/buildroot + +The `/buildroot` is currently setup as an external Buildroot folder following the [recommended structure](https://buildroot.org/downloads/manual/manual.html#customize-dir-structure). As of [Buildroot 2016.11](https://git.buildroot.net/buildroot/tag/?h=2016.11) you may specify multiple BR2_EXTERNAL trees. If you are using a version of Buildroot prior to this, then you will need to manually merge `/buildroot` with your existing Buildroot external tree. + +Now configure buildroot with the [required packages](/buildroot/configs/snapcast_defconfig) (you can also manually add them to your project's existing defconfig): + + $ cd && make BR2_EXTERNAL=/buildroot snapcast_defconfig + +Then use `menuconfig` to configure the rest of your project: + + $ cd && make BR2_EXTERNAL=/buildroot menuconfig + +And finally run the build: + + $ cd && make BR2_EXTERNAL=/buildroot + +##Raspberry Pi (Cross compile) +This example will show you how to add snapcast to [Buildroot](https://buildroot.org/) and compile for Raspberry Pi. + +* https://github.com/nickaknudson/snapcast-pi diff --git a/server/Makefile b/server/Makefile index 4482f278..8be327df 100644 --- a/server/Makefile +++ b/server/Makefile @@ -132,7 +132,7 @@ installfiles: installsystemd: @echo using systemd; \ cp debian/$(BIN).service /lib/systemd/system/$(BIN).service; \ - cp debian/$(BIN).default /etc/default/$(BIN); \ + cp -n debian/$(BIN).default /etc/default/$(BIN); \ systemctl daemon-reload; \ systemctl enable $(BIN); \ systemctl start $(BIN); \ @@ -140,7 +140,7 @@ installsystemd: installsysv: @echo using sysv; \ cp debian/$(BIN).init /etc/init.d/$(BIN); \ - cp debian/$(BIN).default /etc/default/$(BIN); \ + cp -n debian/$(BIN).default /etc/default/$(BIN); \ update-rc.d $(BIN) defaults; \ /etc/init.d/$(BIN) start; \ diff --git a/server/debian/snapserver.service b/server/debian/snapserver.service index 569907b5..312b3c8f 100644 --- a/server/debian/snapserver.service +++ b/server/debian/snapserver.service @@ -1,12 +1,14 @@ [Unit] Description=Snapcast server -After=network.target +After=network-online.target +Requires=network-online.target [Service] EnvironmentFile=-/etc/default/snapserver Type=forking -ExecStart=/usr/bin/snapserver $SNAPSERVER_OPTS -PIDFile=/var/run/snapserver/pid +ExecStart=/usr/sbin/snapserver $SNAPSERVER_OPTS +PIDFile=/var/run/snapserver.pid +Restart=always [Install] WantedBy=multi-user.target diff --git a/server/streamreader/spotifyStream.cpp b/server/streamreader/spotifyStream.cpp index 3c45150e..820128cc 100644 --- a/server/streamreader/spotifyStream.cpp +++ b/server/streamreader/spotifyStream.cpp @@ -42,7 +42,7 @@ SpotifyStream::SpotifyStream(PcmListener* pcmListener, const StreamUri& uri) : P if (password.empty()) throw SnapException("missing parameter \"password\""); - params_ = "--name \"" + devicename + "\" --username \"" + username + "\" --password \"" + password + "\" --bitrate " + bitrate + " --backend stdout"; + params_ = "--name \"" + devicename + "\" --username \"" + username + "\" --password \"" + password + "\" --bitrate " + bitrate + " --backend pipe"; // logO << "params: " << params << "\n"; }