Last active
November 25, 2018 03:02
-
-
Save highgain86j/7fe5cffa98b57bef7433cccc6e043a67 to your computer and use it in GitHub Desktop.
Creates a network audio-sink automatically (without supports for PulseAudio and Jack).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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