Skip to content

Instantly share code, notes, and snippets.

@highgain86j
Last active November 25, 2018 03:02
Show Gist options
  • Save highgain86j/7fe5cffa98b57bef7433cccc6e043a67 to your computer and use it in GitHub Desktop.
Save highgain86j/7fe5cffa98b57bef7433cccc6e043a67 to your computer and use it in GitHub Desktop.
Creates a network audio-sink automatically (without supports for PulseAudio and Jack).
#!/usr/bin/env bash
#sudo groupadd -r audiosink
#sudo useradd -r -M -g audiosink -s /usr/bin/nologin -G audio audiosink
function set_options(){
if ${INSTALL_VBAN}; then
VBAN_ENABLE_ALSA=true
VBAN_ENABLE_PULSE=false
VBAN_ENABLE_JACK=false
VBAN_ENABLE_JACK_VERSION=2
fi
if ${INSTALL_SHAIRPORT}; then
#SHAIRPORT_RUN_AS_USER=default
#SHAIRPORT_RUN_AS_GROUP=default
SHAIRPORT_RUN_AS_USER=tahiro
SHAIRPORT_RUN_AS_GROUP=audio
SHAIRPORT_ENABLE_ALSA=true
SHAIRPORT_ENABLE_PULSE=false
SHAIRPORT_ENABLE_AVAHI=true
SHAIRPORT_ENABLE_SOXR=true
SHAIRPORT_ENABLE_CONVOLUTION=true
SHAIRPORT_ENCRYPTION_TYPE=openssl
SHAIRPORT_ENABLE_ALAC=true
SHAIRPORT_ENABLE_AUTOSTART=true
fi
if ${INSTALL_BLUEZALSA}; then
#BLUEZALSA_RUN_AS_USER=default
#BLUEZALSA_RUN_AS_GROUP=default
BLUEZALSA_RUN_AS_USER=tahiro
BLUEZALSA_RUN_AS_GROUP=audio
BLUEZALSA_ENABLE_AUTOSTART=true
fi
DEPENDENCY_UNSATISFIED=true
}
function install_vban(){
local url="https://github.com/quiniouben/vban.git"
local program_name=`basename ${url} | sed -e 's/\.git$//g'`
local options=()
local prerequisites=()
local enabled=true
if ${INSTALL_VBAN} && ${enabled}; then
if ${VBAN_ENABLE_ALSA}; then
prerequisites=("${prerequisites[@]}" "libasound2-dev")
else
options=("${options[@]}" "--disable-alsa")
fi
if ${VBAN_ENABLE_PULSE}; then
prerequisites=("${prerequisites[@]}" "libpulse-dev")
else
options=("${options[@]}" "--disable-pulseaudio")
fi
if ${VBAN_ENABLE_JACK}; then
if [[ ${VBAN_ENABLE_JACK_VERSION} -eq 2 ]]; then
prerequisites=("${prerequisites[@]}" "libjack-jack2-dev")
else
prerequisites=("${prerequisites[@]}" "libjack-dev")
fi
else
options=("${options[@]}" "--disable-jack")
fi
if [[ "${1}" == "dependency" ]]; then
echo "${prerequisites[@]}"
elif [[ "${1}" == "install" ]]; then
if ${DOWNLOAD_PACKAGE}; then
echo "Downloading ${program_name}"
cd /tmp
if [[ -e ${program_name} ]]; then
rm -rf ${program_name}
fi
git clone ${url}
fi
if ${BUILD_PACKAGE}; then
echo "Building ${program_name}"
cd ${program_name}
./autogen.sh
./configure ${options[@]}
make -j${AVAILABLE_THREADS}
fi
if ${INSTALL_PACKAGE}; then
echo "Installing ${program_name}"
sudo make install
fi
fi
fi
}
function alac_for_shairport(){
local url="https://github.com/mikebrady/alac.git"
local program_name=`basename ${url} | sed -e 's/\.git$//g'`
local options=()
local prerequisites=("build-essential" "git" "autoconf" "automake" "libtool")
if [[ ! -e /usr/local/include/alac ]]; then
if [[ "${1}" == "dependency" ]]; then
echo "${prerequisites[@]}"
elif [[ "${1}" == "install" ]]; then
cd /tmp
if [[ -e ${program_name} ]]; then
rm -rf ${program_name}
fi
git clone ${url}
cd ${program_name}
autoreconf -fi
./configure
make
sudo make install
sudo ldconfig
fi
fi
}
function install_shairport(){
local url="https://github.com/mikebrady/shairport-sync.git"
local program_name=`basename ${url} | sed -e 's/\.git$//g'`
local systemd_file
local systemd_file_name="shairport-sync.service"
local config_file_dir="/etc"
local config_file="${config_file_dir}/shairport-sync.conf"
local user
local group
local reload_systemd=false
local item
local options=("--sysconfdir=${config_file_dir}" "--with-ssl=openssl" "--with-metadata" "--with-systemd")
local prerequisites=("build-essential" "git" "xmltoman" "autoconf" "automake" "libtool" "libdaemon-dev" "libpopt-dev" "libconfig-dev")
local enabled=true
local line
local line_alt
if ${INSTALL_SHAIRPORT} && ${enabled}; then
if ${SHAIRPORT_ENABLE_ALSA}; then
prerequisites=("${prerequisites[@]}" "libasound2-dev")
options=("${options[@]}" "--with-alsa")
fi
if ${SHAIRPORT_ENABLE_PULSE}; then
prerequisites=("${prerequisites[@]}" "libpulse-dev")
options=("${options[@]}" "--with-pulseaudio")
fi
if ${SHAIRPORT_ENABLE_AVAHI}; then
prerequisites=("${prerequisites[@]}" "avahi-daemon" "libavahi-client-dev")
options=("${options[@]}" "--with-avahi")
fi
if ${SHAIRPORT_ENABLE_SOXR}; then
prerequisites=("${prerequisites[@]}" "libsoxr-dev")
options=("${options[@]}" "--with-soxr")
fi
if ${SHAIRPORT_ENABLE_CONVOLUTION}; then
prerequisites=("${prerequisites[@]}" "libsndfile1-dev")
options=("${options[@]}" "--with-convolution")
fi
if [[ "${SHAIRPORT_ENCRYPTION_TYPE}" != "" ]]; then
options=("${options[@]}" "--with-ssl=${SHAIRPORT_ENCRYPTION_TYPE}")
if [[ "${SHAIRPORT_ENCRYPTION_TYPE}" == "openssl" ]]; then
prerequisites=("${prerequisites[@]}" "libssl-dev")
elif [[ "${SHAIRPORT_ENCRYPTION_TYPE}" == "mbedtls" ]]; then
prerequisites=("${prerequisites[@]}" "libmbedtls-dev")
fi
fi
if ${SHAIRPORT_ENABLE_ALAC}; then
prerequisites=("${prerequisites[@]}" `alac_for_shairport dependency`)
options=("${options[@]}" "--with-apple-alac")
fi
if [[ "${1}" == "dependency" ]]; then
prerequisites=(`for item in ${prerequisites[@]}; do echo ${item}; done | sort | uniq`)
echo "${prerequisites[@]}"
elif [[ "${1}" == "install" ]]; then
if ${DOWNLOAD_PACKAGE}; then
echo "Downloading ${program_name}"
cd /tmp
if [[ -e ${program_name} ]]; then
rm -rf ${program_name}
fi
git clone ${url}
fi
if ${BUILD_PACKAGE}; then
echo "Building ${program_name}"
if ${SHAIRPORT_ENABLE_ALAC}; then
alac_for_shairport install
fi
cd /tmp
cd ${program_name}
autoreconf -i -f
./configure ${options[@]}
make -j${AVAILABLE_THREADS}
fi
if ${INSTALL_PACKAGE}; then
echo "Installing ${program_name}"
if [[ "`which ${program_name}`" != "" ]]; then
sudo systemctl stop ${systemd_file_name}
sudo systemctl disable ${systemd_file_name}
sudo find /etc/systemd/system/ -type f -name ${systemd_file_name} -delete
sudo find /lib/systemd/system/ -type f -name ${systemd_file_name} -delete
fi
if [[ ! -e ${config_file}.bak ]] && [[ -e ${config_file} ]]; then
sudo mv ${config_file} ${config_file}.bak
fi
sudo make install
sudo systemctl disable ${systemd_file_name}
for systemd_file in `sudo find /run/systemd /lib/systemd /etc/systemd -type f -name ${systemd_file_name}`; do
if [[ -e ${systemd_file} ]]; then
break
fi
done
user=`cat ${systemd_file} | egrep '^User\=' | awk -F'=' '{print $2}'`
group=`cat ${systemd_file} | egrep '^Group\=' | awk -F'=' '{print $2}'`
if [[ "${SHAIRPORT_RUN_AS_USER}" != "" ]] && [[ "${SHAIRPORT_RUN_AS_USER}" != "default" ]] && [[ "${SHAIRPORT_RUN_AS_USER}" != "${user}" ]]; then
sudo sed -i "s/^User=${user}/User=${SHAIRPORT_RUN_AS_USER}/g" ${systemd_file}
reload_systemd=true
if [[ "`getent passwd ${user}`" != "" ]]; then
sudo userdel ${user}
fi
fi
if [[ "${SHAIRPORT_RUN_AS_GROUP}" != "" ]] && [[ "${SHAIRPORT_RUN_AS_GROUP}" != "default" ]] && [[ "${SHAIRPORT_RUN_AS_GROUP}" != "${group}" ]]; then
sudo sed -i "s/^Group=${group}/Group=${SHAIRPORT_RUN_AS_GROUP}/g" ${systemd_file}
reload_systemd=true
if [[ "`getent group ${group}`" != "" ]]; then
sudo groupdel ${group}
fi
fi
if [[ -e ${config_file}.sample ]] && [[ -e ${config_file}.bak ]]; then
sudo mv ${config_file}.bak ${config_file}
fi
if ${SHAIRPORT_ENABLE_SOXR}; then
line="`cat ${config_file} | egrep '.+' | egrep -v '^\/\/|^[a-z]+ =|^\{|^\}' | egrep 'interpolation = \"[a-z]+\";'`"
if [[ "${line}" == "" ]]; then
line="`cat ${config_file} | egrep 'interpolation = \"[a-z]+\";'`"
fi
line_alt="`echo "${line}" | sed -e 's/interpolation \= \"basic\";/interpolation \= \"soxr\";/g' -e 's/^\/\///g'`"
if [[ "${line}" != "${line_alt}" ]]; then
sudo sed -i "s|${line}|${line_alt}|g" ${config_file}
fi
fi
if ${reload_systemd}; then
sudo systemctl daemon-reload
fi
if ${SHAIRPORT_ENABLE_AUTOSTART}; then
sudo systemctl start ${systemd_file_name}
sudo systemctl enable ${systemd_file_name}
sleep 0.5
sudo systemctl status ${systemd_file_name}
fi
fi
fi
fi
}
function install_bluezalsa(){
local url="https://github.com/Arkq/bluez-alsa"
local program_name=`basename ${url} | sed -e 's/\.git$//g'`
local systemd_files_dir="/etc/systemd/system"
local systemd_file
local systemd_file_name_bluezalsa="${systemd_files_dir}/bluezalsa.service"
local systemd_file_name_bluezalsa_aplay="${systemd_files_dir}/[email protected]"
local config_file_dir="/etc/bluetooth"
local config_file_main="${config_file_dir}/main.conf"
local config_file_audio="${config_file_dir}/audio.conf"
local user
local group
local reload_systemd=false
local item
local alsaplugindir=`find /usr/lib/ -type d -name alsa-lib`
local options=("--disable-hcitop" "--with-alsaplugindir=${alsaplugindir}")
local prerequisites=("libasound2-dev" "dh-autoreconf" "libortp-dev" "bluez" "bluez-tools" "libbluetooth-dev" "libusb-dev" "libglib2.0-dev" "libudev-dev" "libical-dev" "libreadline-dev" "libsbc1" "libsbc-dev")
local enabled=true
local line
local line_alt
local sound_device="plughw:rpu200,0"
local udev_rule_file=/etc/udev/rules.d/99-input.rules
if ${INSTALL_BLUEZALSA} && ${enabled}; then
if [[ "${1}" == "dependency" ]]; then
prerequisites=(`for item in ${prerequisites[@]}; do echo ${item}; done | sort | uniq`)
echo "${prerequisites[@]}"
elif [[ "${1}" == "install" ]]; then
if ${DOWNLOAD_PACKAGE}; then
echo "Downloading ${program_name}"
cd /tmp
if [[ -e ${program_name} ]]; then
rm -rf ${program_name}
fi
git clone ${url}
fi
if ${BUILD_PACKAGE}; then
echo "Building ${program_name}"
cd /tmp
cd ${program_name}
autoreconf --install
mkdir build
cd build
../configure ${options[@]}
make -j${AVAILABLE_THREADS}
fi
if ${INSTALL_PACKAGE}; then
echo "Installing ${program_name}"
if [[ "`which ${program_name}`" != "" ]]; then
sudo systemctl stop ${systemd_file_name_bluezalsa}
sudo systemctl disable ${systemd_file_name_bluezalsa}
sudo find /etc/systemd/system/ -type f -name ${systemd_file_name_bluezalsa} -delete
sudo find /lib/systemd/system/ -type f -name ${systemd_file_name_bluezalsa} -delete
fi
if [[ ! -e ${config_file_main}.bak ]] && [[ -e ${config_file_main} ]]; then
sudo mv ${config_file_main} ${config_file_main}.bak
fi
if [[ ! -e ${config_file_audio}.bak ]] && [[ -e ${config_file_audio} ]]; then
sudo mv ${config_file_audio} ${config_file_audio}.bak
fi
sudo make install
exit
echo "Update file ${config_file_main}"
while read line; do
line=`echo ${line} | grep 'Class = '`
if [[ "${line}" != "" ]]; then
sudo sed -i "s|${line}|Class = 0x20041C|g" ${config_file_main}
break
fi
done < ${config_file_main}
cat <<EOF | sudo tee ${config_file_audio}
[General]
Class = 0x20041C
Enable = Source,Sink,Media,Socket
EOF
cat <<EOF | sudo tee ${systemd_file_name_bluezalsa}
[Unit]
Description=BluezAlsa proxy
Requires=bluetooth.service
After=bluetooth.service
[Service]
Type=simple
User=${BLUEZALSA_RUN_AS_USER}
Group=audio
ExecStart=/usr/bin/bluealsa
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable `basename ${systemd_file_name_bluezalsa}`
cat <<EOF | sudo tee ${systemd_file_name_bluezalsa_aplay}
[Unit]
Description=BlueAlsa-Aplay %I -d${sound_device}
Requires=bluetooth.service bluealsa.service
[Service]
Type=simple
User=${BLUEZALSA_RUN_AS_USER}
Group=audio
ExecStart=/usr/bin/bluealsa-aplay %I -d${sound_device}
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF | sudo tee /home/${BLUEZALSA_RUN_AS_USER}/a2dp-autoconnect
#!/bin/bash
# at each BT connection/disconnection start/stop the service bluealsa-aplay
function log {
sudo echo "[\$(date)]: \$*" >> /var/log/a2dp-autoconnect
}
BTMAC=\${NAME//\"/}
if [ "\${ACTION}" = "remove" ]; then
log "Stop Played Connection " \${BTMAC}
sudo systemctl stop bluealsa-aplay@\${BTMAC}
elif [ "\${ACTION}" = "add" ]; then
log "Start Played Connection " \${BTMAC}
sudo systemctl start bluealsa-aplay@\${BTMAC}
else
log "Other action " \${ACTION}
fi
EOF
echo -e "KERNEL==\"input[0-9]\*\", RUN+=\"/home/${BLUEZALSA_RUN_AS_USER}/a2dp-autoconnect\"" | sudo tee ${udev_rule_file}
sudo chmod a+rwx /home/${BLUEZALSA_RUN_AS_USER}/a2dp-autoconnect
sudo touch /var/log/a2dp-autoconnect
sudo chmod a+rw /var/log/a2dp-autoconnect
if ${reload_systemd}; then
sudo systemctl daemon-reload
fi
if ${BLUEZALSA_ENABLE_AUTOSTART}; then
sudo systemctl start `basename ${systemd_file_name_bluezalsa}`
sudo systemctl enable `basename ${systemd_file_name_bluezalsa}`
sleep 0.5
sudo systemctl status `basename ${systemd_file_name_bluezalsa}`
fi
fi
fi
fi
}
function install_prereq(){
local arr_prerequisites=()
local arr_cpu_core=()
local available_threads
local item
arr_prerequisites=("build-essential" "git" "`install_vban dependency`" "`install_shairport dependency`" "`install_bluezalsa dependency`")
arr_cpu_core=(`cat /proc/cpuinfo | egrep '^processor' | awk '{print $3}'`)
available_threads=`expr ${#arr_cpu_core[@]} + 1`
arr_prerequisites=(`for item in ${arr_prerequisites[@]}; do echo ${item}; done | sort | uniq`)
echo "${arr_prerequisites[@]}"
if ${INSTALL_PREREQUISITES} && [[ ${#arr_prerequisites[@]} -gt 0 ]]; then
sudo apt-get install ${arr_prerequisites[@]}
fi
if ${BUILD_PACKAGE} && [[ "`echo ${AVAILABLE_THREADS} | egrep '^[0-9]+$'`" == "" ]]; then
AVAILABLE_THREADS=${available_threads}
fi
}
INSTALL_VBAN=false
INSTALL_SHAIRPORT=false
INSTALL_BLUEZALSA=false
case ${1} in
vban ) INSTALL_VBAN=true;;
shairport ) INSTALL_SHAIRPORT=true;;
bluezalsa ) INSTALL_BLUEZALSA=true;;
all ) INSTALL_VBAN=true
INSTALL_SHAIRPORT=true
INSTALL_BLUEZALSA=true;;
* ) echo "Invalid option."
exit;;
esac
INSTALL_PACKAGE=false
BUILD_PACKAGE=false
case ${2} in
build ) BUILD_PACKAGE=true;;
install ) INSTALL_PACKAGE=true;;
* ) echo "Invalid option."
exit;;
esac
set_options
if ${INSTALL_PACKAGE}; then
BUILD_PACKAGE=${INSTALL_PACKAGE}
fi
DOWNLOAD_PACKAGE=false
if ${BUILD_PACKAGE}; then
DOWNLOAD_PACKAGE=${BUILD_PACKAGE}
fi
INSTALL_PREREQUISITES=false
if ${DOWNLOAD_PACKAGE} || ${DEPENDENCY_UNSATISFIED}; then
INSTALL_PREREQUISITES=true
fi
AVAILABLE_THREADS="default"
install_prereq
install_vban install
install_shairport install
install_bluezalsa install
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment