diff --git a/sound/shairport-sync/Makefile b/sound/shairport-sync/Makefile index cd60f97d3..aa4fa7b2a 100644 --- a/sound/shairport-sync/Makefile +++ b/sound/shairport-sync/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=shairport-sync -PKG_VERSION:=2.1.15 +PKG_VERSION:=2.4.1 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git @@ -17,13 +17,12 @@ PKG_SOURCE_URL:=git://github.com/mikebrady/shairport-sync.git PKG_SOURCE_VERSION:=$(PKG_VERSION) PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_MAINTAINER:=Ted Hess +PKG_MAINTAINER:=Ted Hess , Mike Brady PKG_LICENSE:=MIT PKG_LICENSE_FILES:=COPYING LICENSES shairport.c PKG_BUILD_PARALLEL:=1 - PKG_FIXUP:=autoreconf include $(INCLUDE_DIR)/package.mk @@ -32,31 +31,70 @@ CONFIGURE_ARGS+= \ --with-alsa \ --with-avahi \ --with-soxr \ - --with-ssl=openssl + --with-metadata +ifeq ($(BUILD_VARIANT),openssl) + CONFIGURE_ARGS+= --with-ssl=openssl +endif +ifeq ($(BUILD_VARIANT),polarssl) + CONFIGURE_ARGS+= --with-ssl=polarssl +endif -define Package/shairport-sync +define Package/shairport-sync/default SECTION:=sound CATEGORY:=Sound - TITLE:=iPhone/iTunes compatible audio player - DEPENDS:= +libpthread +libopenssl +libavahi-client +alsa-lib +libdaemon +libsoxr +libpopt - MAINTAINER:=Mike Brady + TITLE:=iPhone/iTunes/AirPlay/Quicktime Player compatible Audio Player + DEPENDS:=@AUDIO_SUPPORT +libpthread +libavahi-client +alsa-lib +libconfig +libdaemon +libsoxr +libpopt + URL:=http://github.com/mikebrady/shairport-sync +endef + +define Package/shairport-sync-openssl + $(Package/shairport-sync/default) + TITLE+= (openssl) + DEPENDS+= +PACKAGE_shairport-sync-openssl:libopenssl + VARIANT:=openssl +endef + +define Package/shairport-sync-polarssl + $(Package/shairport-sync/default) + TITLE+= (polarssl) + DEPENDS+= +PACKAGE_shairport-sync-polarssl:libpolarssl + VARIANT:=polarssl + DEFAULT_VARIANT:=1 +endef + +define Package/shairport-sync/default/description + Shairport Sync plays audio from iTunes and AirPlay sources, including + iOS devices, Quicktime Player and third party sources such as forkedDaapd. + Audio played by a Shairport Sync-powered device stays synchronised with the source + and hence with similar devices playing the same source. + Thus, for example, synchronised multi-room audio is possible without difficulty. + (Hence the name Shairport Sync, BTW.) + Shairport Sync does not support AirPlay video or photo streaming. + Ensure Kernel Modules > Sound Support > kmod-sound-core is selected. + Also select kmod-usb-audio if you want to use USB-connected sound cards. endef +Package/shairport-sync-openssl/description = $(Package/shairport-sync/default/description) +Package/shairport-sync-polarssl/description = $(Package/shairport-sync/default/description) -define Package/shairport-sync/description - Shairport Sync is server software that implements the Apple-originated RAOP protocol for - playback of audio from a compatible remote client such as the iPhone, iTunes, Apple TV, Quicktime Player or forked-daapd. - Shairport Sync implements audio synchronisation, supporting multi-room use. - Shairport Sync supports audio only. +define Package/shairport-sync/default/conffiles +/etc/shairport-sync.conf endef +Package/shairport-sync-openssl/conffiles = $(Package/shairport-sync/default/conffiles) +Package/shairport-sync-polarssl/conffiles = $(Package/shairport-sync/default/conffiles) -define Package/shairport-sync/install +define Package/shairport-sync/default/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/shairport-sync $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/shairport-sync.conf $(1)/etc/shairport-sync.conf $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/shairport-sync.init $(1)/etc/init.d/shairport-sync $(INSTALL_DIR) $(1)/etc/config $(INSTALL_DATA) ./files/shairport-sync.config $(1)/etc/config/shairport-sync endef +Package/shairport-sync-openssl/install = $(Package/shairport-sync/default/install) +Package/shairport-sync-polarssl/install = $(Package/shairport-sync/default/install) -$(eval $(call BuildPackage,shairport-sync)) +$(eval $(call BuildPackage,shairport-sync-openssl)) +$(eval $(call BuildPackage,shairport-sync-polarssl)) diff --git a/sound/shairport-sync/files/shairport-sync.config b/sound/shairport-sync/files/shairport-sync.config index f72c78549..289a37855 100644 --- a/sound/shairport-sync/files/shairport-sync.config +++ b/sound/shairport-sync/files/shairport-sync.config @@ -1,35 +1,53 @@ -# Uncomment the stanza you want, and make sure to comment out the others, especially duplicate options. +# Use your own config file +config shairport-sync 'shairport_sync_file' + option disabled '1' + option respawn '1' + option conf_custom '1' + option conf_file '/etc/shairport-sync.conf' -#Arguments and defaults are as follows -config shairport-sync main -# option name 'Shairport Sync' #default name, "Shairport Sync on %d" -# option device default #default soundcard, volume control by software - #(Troubleshooting hint: make sure the soundcard's volume is turned up fully -- use alsamixer or amixer) -# option airplaylatency 88200 -# option ituneslatency 99400 -# option port 5000 -# option stuffing basic #options are 'basic' or 'soxr' if shairport-sync was compiled with soxr support -# option awaitactioncompletion false #[don't] wait until beforeaction or afteraction completes -# option beforeaction #action must be a fully qualified program with no arguments. Default no action. -# option afteraction #action must be a fully qualified program with no arguments. Default no action. -# option devicetype -# option volumecontrolname - -#Here are some sample stanzas: - -#For Raspberry Pi using the built-in soundcard for the headphone jack -# option device 'hw:0' -# option devicetype hardware -# option volumecontrolname Master - -#For Raspberry Pi with the "3D Sound" USB Soundcard -# option name 'Pi' -# option device 'hw:1' -# option devicetype hardware -# option volumecontrolname Speaker - -#For Raspberry Pi with the first generation iMic or the Topping TP30 Class T Digital Mini Amplifier -# option name 'Kitchen' -# option device 'hw:1' -# option devicetype hardware -# option volumecontrolname PCM +# Use OpenWrt UCI config +config shairport-sync 'shairport_sync' + option disabled '1' + option respawn '1' + # General + option name 'Shairport-Sync' + option password '' + option interpolation '' # basic/soxr + option output_backend '' # alsa/pipe/stdout/ao/dummy/pulse/sndio + option mdns_backend '' # avahi/external-avahi/dns-sd/external-dns-sd/tinysvcmdns + option port '' # 5000 + option udp_port_base '' # 6001 + option udp_port_range '' # 100 + option statistics '' # no/yes + option drift '' # 88 + option resync_threshold '' # 2205 + option log_verbosity '' # 0/1/2/3 + option ignore_volume_control '' # no/yes + # Latencies + option latencies_default '' # 88200 + option latencies_itunes '' # 99400 + option latencies_airplay '' # 88200 + option latencies_forked_daapd '' # 99400 + # Metadata + option metadata_enabled '' # no/yes + option metadata_cover_art '' # no/yes + option metadata_pipe_name '' # /tmp/shairport-sync-metadata + # Session Control + option sesctl_run_before_play_begins '' # /etc/shairport-sync-start.sh + option sesctl_run_after_play_ends '' # /etc/shairport-sync-stop.sh + option sesctl_wait_for_completion '' # no/yes + option sesctl_session_interruption '' # no/yes + option sesctl_session_timeout '' # 120 + # ALSA + option alsa_output_device '' # default + option alsa_mixer_control_name '' # PCM + option alsa_mixer_device '' # default + option alsa_latency_offset '' # 0 + option alsa_buffer_length '' # 6615 + # Pipe + option pipe_name '' # /tmp/shairport-sync-audio + option pipe_latency_offset '' # 0 + option pipe_buffer_length '' # 44100 + # Stdout + option stdout_latency_offset '' # 0 + option stdout_buffer_length '' # 44100 diff --git a/sound/shairport-sync/files/shairport-sync.init b/sound/shairport-sync/files/shairport-sync.init old mode 100755 new mode 100644 index f49e1e3cd..2631401c1 --- a/sound/shairport-sync/files/shairport-sync.init +++ b/sound/shairport-sync/files/shairport-sync.init @@ -1,77 +1,134 @@ #!/bin/sh /etc/rc.common +# Copyright (C) 2015 OpenWrt.org -NAME='shairport-sync' START=99 - USE_PROCD=1 -append_arg() { +append_num() { local cfg="$1" - local var="$2" - local opt="$3" - local def="$4" + local file="$2" + local var="$3" + local opt="$4" + local def="$5" local val config_get val "$cfg" "$var" - [ -n "$val" -o -n "$def" ] && procd_append_param command $opt "${val:-$def}" + [ -n "$val" -o -n "$def" ] && echo -e "\t$opt = ${val:-$def};" >> $file } - -append_bool() { +append_str() { local cfg="$1" - local var="$2" - local opt="$3" - local def="$4" + local file="$2" + local var="$3" + local opt="$4" + local def="$5" local val - config_get_bool val "$cfg" "$var" "$def" - [ "$val" = 1 ] && procd_append_param command "$opt" + config_get val "$cfg" "$var" + [ -n "$val" -o -n "$def" ] && echo -e "\t$opt = \"${val:-$def}\";" >> $file } -start_shairport_service() { +start_instance() { local cfg=$1 - local stuffing - local device + local conf_custom conf_file aux + + config_get_bool aux "$cfg" 'disabled' '0' + [ "$aux" = 1 ] && return 1 + + config_get_bool conf_custom "$cfg" 'conf_custom' '0' + config_get conf_file "$cfg" "conf_file" + if [ $conf_custom -ne 1 ] && [ ! -n "$conf_file" ]; then + mkdir -p /var/etc + conf_file="/var/etc/shairport-sync-${cfg}.conf" + + echo -e "// Automatically generated from UCI config\n" > $conf_file + + # General + echo -e "general =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" name "name" + append_str "$cfg" "$conf_file" password "password" + append_str "$cfg" "$conf_file" interpolation "interpolation" + append_str "$cfg" "$conf_file" output_backend "output_backend" + append_str "$cfg" "$conf_file" mdns_backend "mdns_backend" + append_num "$cfg" "$conf_file" port "port" + append_num "$cfg" "$conf_file" udp_port_base "udp_port_base" + append_num "$cfg" "$conf_file" udp_port_range "udp_port_range" + append_str "$cfg" "$conf_file" statistics "statistics" + append_num "$cfg" "$conf_file" drift "drift" + append_num "$cfg" "$conf_file" resync_threshold "resync_threshold" + append_num "$cfg" "$conf_file" log_verbosity "log_verbosity" + append_str "$cfg" "$conf_file" ignore_volume_control "ignore_volume_control" + echo -e "};\n" >> $conf_file + + # Latencies + echo -e "latencies =" >> $conf_file + echo -e "{" >> $conf_file + append_num "$cfg" "$conf_file" latencies_default "default" + append_num "$cfg" "$conf_file" latencies_itunes "itunes" + append_num "$cfg" "$conf_file" latencies_airplay "airplay" + append_num "$cfg" "$conf_file" latencies_forked_daapd "forkedDaapd" + echo -e "};\n" >> $conf_file + + # Metadata + echo -e "metadata =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" metadata_enabled "enabled" + append_str "$cfg" "$conf_file" metadata_cover_art "include_cover_art" + append_str "$cfg" "$conf_file" metadata_pipe_name "pipe_name" + echo -e "};\n" >> $conf_file + + # Session control + echo -e "sessioncontrol =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" sesctl_run_before_play_begins "run_this_before_play_begins" + append_str "$cfg" "$conf_file" sesctl_run_after_play_ends "run_this_after_play_ends" + append_str "$cfg" "$conf_file" sesctl_wait_for_completion "wait_for_completion" + append_str "$cfg" "$conf_file" sesctl_session_interruption "allow_session_interruption" + append_num "$cfg" "$conf_file" sesctl_session_timeout "session_timeout" + echo -e "};\n" >> $conf_file + + # Alsa audio back end + echo -e "alsa =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" alsa_output_device "output_device" + append_str "$cfg" "$conf_file" alsa_mixer_control_name "mixer_control_name" + append_str "$cfg" "$conf_file" alsa_mixer_device "mixer_device" + append_num "$cfg" "$conf_file" alsa_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" alsa_buffer_length "audio_backend_buffer_desired_length" + echo -e "};\n" >> $conf_file + + # Pipe audio back end + echo -e "pipe =" >> $conf_file + echo -e "{" >> $conf_file + append_str "$cfg" "$conf_file" pipe_name "name" + append_num "$cfg" "$conf_file" pipe_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" pipe_buffer_length "audio_backend_buffer_desired_length" + echo -e "};\n" >> $conf_file + + # Stdout audio back end + echo -e "stdout =" >> $conf_file + echo -e "{" >> $conf_file + append_num "$cfg" "$conf_file" stdout_latency_offset "audio_backend_latency_offset" + append_num "$cfg" "$conf_file" stdout_buffer_length "audio_backend_buffer_desired_length" + echo -e "};\n" >> $conf_file + fi procd_open_instance - procd_set_param command /usr/bin/$NAME - - append_arg "$cfg" name "-a" - append_arg "$cfg" port "-p" - append_arg "$cfg" airplaylatency "-A" - append_arg "$cfg" ituneslatency "-i" - - config_get stuffing "$cfg" stuffing "" - - if [ -n "$stuffing" ] ; then - case "x$stuffing" in - ( "xbasic" ) procd_append_param command -S basic ;; - ( "xsoxr" ) procd_append_param command -S soxr ;; - ( * ) logger "bad argument for -S option -- should be \"basic\" or \"soxr\"" ;; - esac - fi - - append_arg "$cfg" beforeaction "-B" - append_arg "$cfg" afteraction "-E" - append_bool "$cfg" awaitactioncompletion "-w" - - config_get device "$cfg" device "" - if [ -n "$device" ] ; then - procd_append_param command "--" - append_arg "$cfg" device "-d" - append_arg "$cfg" devicetype "-t" - append_arg "$cfg" volumecontrolname "-c" - fi + procd_set_param command /usr/bin/shairport-sync + procd_append_param command -c $conf_file + + config_get_bool aux "$cfg" 'respawn' '0' + [ "$aux" = 1 ] && procd_set_param respawn procd_close_instance } -service_triggers() { - procd_add_reload_trigger $NAME -} +service_triggers() { + procd_add_reload_trigger "shairport-sync" +} start_service() { - config_load $NAME - # Just a single instance - start_shairport_service "main" + config_load shairport-sync + config_foreach start_instance shairport-sync }