Compare commits
No commits in common. "main" and "1.1.1" have entirely different histories.
3 changed files with 65 additions and 106 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,4 +3,3 @@ debian/debhelper-build-stamp
|
||||||
debian/files
|
debian/files
|
||||||
debian/pulseaudio-tcp.substvars
|
debian/pulseaudio-tcp.substvars
|
||||||
debian/pulseaudio-tcp
|
debian/pulseaudio-tcp
|
||||||
*.sw*
|
|
||||||
|
|
|
@ -22,24 +22,16 @@
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
cat >&2 <<EOF
|
cat >&2 <<EOF
|
||||||
# pulseaudio-tcp - Connect to remote PulseAudio/Pipewire Server
|
Usage: $0 [OPTIONS] OPERATION
|
||||||
## Usage:
|
Options:
|
||||||
\`$0 [OPTION ...] OPERATION ...\`
|
--debug Enable additional debug output for start and stop operations.
|
||||||
## Options:
|
--no-gui Do not display GUI dialogs, use terminal for input and output.
|
||||||
* \`--debug\`: Enable additional debug output for start and stop operations.
|
Operations:
|
||||||
* \`--no-gui\`: Do not display GUI dialogs, use terminal for input and output.
|
setup Interactively gather settings.
|
||||||
* \`--cookie COOKIE\`: Pass Pulseaudio cookie as option value instead of copying
|
start Start redirection to remote host.
|
||||||
from remote_host. Expects value to be Base64-encoded.
|
stop Stop redirection to remote host.
|
||||||
## Operations:
|
restart Stop and then start redirection.
|
||||||
* \`setup\`: Interactively gather settings.
|
status Check if redirection is set up and enabled.
|
||||||
* \`start\`: Start redirection to remote host.
|
|
||||||
* \`stop\`: Stop redirection to remote host.
|
|
||||||
* \`restart\`: Stop and then start redirection.
|
|
||||||
* \`status\`: Check if redirection is set up and enabled.
|
|
||||||
## Environment Variables:
|
|
||||||
* \`PULSEAUDIO_TCP_SSH_ADDARGS\`:
|
|
||||||
If set, specifies additional commandline arguments for calls to \`ssh\`.
|
|
||||||
Example: \`PULSEAUDIO_TCP_SSH_ADDARGS=-v pulseaudio-tcp --no-gui start\`
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +68,14 @@ info() {
|
||||||
|
|
||||||
debug() {
|
debug() {
|
||||||
if "$debug" ; then
|
if "$debug" ; then
|
||||||
|
log DEBUG "$@"
|
||||||
|
else
|
||||||
gui=false log DEBUG "$@"
|
gui=false log DEBUG "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_ssh() {
|
_ssh() {
|
||||||
if ssh "${_ssh_arguments[@]}" -S "$USER"-pulseaudio "$remote_user"@"$remote_ip" "$@" ; then
|
if ssh -o PasswordAuthentication=no -S "$USER"-pulseaudio "$remote_user"@"$remote_ip" "$@" ; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
error "SSH remote_ip=$remote_ip failed."
|
error "SSH remote_ip=$remote_ip failed."
|
||||||
|
@ -243,23 +237,17 @@ do_status() {
|
||||||
if ! _ssh pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
if ! _ssh pactl list modules | grep -Fq "Name: module-native-protocol-tcp" ; then
|
||||||
errors+=("PulseAudio module \"module-native-protocol-tcp\" is not loaded on remote host $remote_ip.")
|
errors+=("PulseAudio module \"module-native-protocol-tcp\" is not loaded on remote host $remote_ip.")
|
||||||
rv=1
|
rv=1
|
||||||
else
|
|
||||||
debug "PulseAudio module \"module-native-protocol-tcp\" is loaded on remote host $remote_ip."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if "$outbound" ; then
|
if "$outbound" ; then
|
||||||
if ! pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
if ! pactl list modules | grep -Fq "Name: module-tunnel-sink" ; then
|
||||||
errors+=("PulseAudio module \"module-tunnel-sink\" is not loaded.")
|
errors+=("PulseAudio module \"module-tunnel-sink\" is not loaded.")
|
||||||
rv=1
|
rv=1
|
||||||
else
|
|
||||||
debug "PulseAudio module \"module-tunnel-sink\" is loaded."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! pactl get-default-sink | grep -Fq "tunnel-sink.tcp:127.0.0.1" ; then
|
if ! pactl get-default-sink | grep -Fq "tunnel-sink.tcp:127.0.0.1" ; then
|
||||||
errors+=("\"tunnel-sink.tcp:127.0.0.1\" is not the default PulseAudio sink.")
|
errors+=("\"tunnel-sink.tcp:127.0.0.1\" is not the default PulseAudio sink.")
|
||||||
rv=1
|
rv=1
|
||||||
else
|
|
||||||
debug "\"tunnel-sink.tcp:127.0.0.1\" is the default PulseAudio sink."
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -267,8 +255,6 @@ do_status() {
|
||||||
if ! pactl list modules | grep -Fq "Name: module-tunnel-source" ; then
|
if ! pactl list modules | grep -Fq "Name: module-tunnel-source" ; then
|
||||||
errors+=("PulseAudio module \"module-tunnel-source\" is not loaded.")
|
errors+=("PulseAudio module \"module-tunnel-source\" is not loaded.")
|
||||||
rv=1
|
rv=1
|
||||||
else
|
|
||||||
debug "PulseAudio module \"module-tunnel-source\" is loaded."
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -281,20 +267,9 @@ do_status() {
|
||||||
return "$rv"
|
return "$rv"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use PulseAudio cookie from --cookie option value or remote host
|
# Acquire PulseAudio cookie from remote host
|
||||||
sync_pa_cookie() {
|
sync_pa_cookie() {
|
||||||
if ! [[ -d ~/.config/pulse ]] || ! [[ -w ~/.config/pulse ]] ; then
|
if _scp "$remote_user"@"$remote_ip":.config/pulse/cookie ~/.config/pulse/cookie ; then
|
||||||
error "Local directory ~/.config/pulse does not exist or is not writeable."
|
|
||||||
return 1
|
|
||||||
elif [[ -n $cookie ]] ; then
|
|
||||||
if echo "$cookie" | base64 -d > ~/.config/pulse/cookie ; then
|
|
||||||
debug "Using PulseAudio cookie value as passed on the command line ..."
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
error "Decoding Base64 value of option --cookie failed."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
elif _scp "$remote_user"@"$remote_ip":.config/pulse/cookie ~/.config/pulse/cookie ; then
|
|
||||||
debug "Synced PulseAudio cookie from remote host $remote_ip."
|
debug "Synced PulseAudio cookie from remote host $remote_ip."
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
|
@ -475,15 +450,10 @@ do_stop() {
|
||||||
##
|
##
|
||||||
# Arguments
|
# Arguments
|
||||||
|
|
||||||
operations=()
|
operation=
|
||||||
cookie=
|
|
||||||
no_more_options=false
|
no_more_options=false
|
||||||
# shellcheck disable=SC2034
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]] ; do
|
|
||||||
arg=$1
|
|
||||||
shift
|
|
||||||
|
|
||||||
|
for arg in "$@" ; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
--)
|
--)
|
||||||
no_more_options=true
|
no_more_options=true
|
||||||
|
@ -491,11 +461,6 @@ while [[ $# -gt 0 ]] ; do
|
||||||
--*)
|
--*)
|
||||||
"$no_more_options" && { gui=false error "Option arguments may not preceed non-option arguments." ; exit 1 ; }
|
"$no_more_options" && { gui=false error "Option arguments may not preceed non-option arguments." ; exit 1 ; }
|
||||||
;;&
|
;;&
|
||||||
--cookie)
|
|
||||||
[[ $# -eq 0 ]] && { gui=false error "Missing argument for option \"--cookie\"" ; exit 1 ; }
|
|
||||||
cookie=$1
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
--debug)
|
--debug)
|
||||||
debug_cmdline=true
|
debug_cmdline=true
|
||||||
;;
|
;;
|
||||||
|
@ -506,7 +471,8 @@ while [[ $# -gt 0 ]] ; do
|
||||||
help_cmdline=true
|
help_cmdline=true
|
||||||
;;
|
;;
|
||||||
start|stop|restart|setup|status)
|
start|stop|restart|setup|status)
|
||||||
operations+=("$arg")
|
[[ -z $operation ]] || { gui=false error "Multiple operations are not supported." ; exit 1 ; }
|
||||||
|
operation=$arg
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
gui=false error "Unsupported argument (try \"--help\")"
|
gui=false error "Unsupported argument (try \"--help\")"
|
||||||
|
@ -518,16 +484,6 @@ done
|
||||||
##
|
##
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
_ssh_arguments=(
|
|
||||||
-o
|
|
||||||
PasswordAuthentication=no
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ -n $PULSEAUDIO_TCP_SSH_ADDARGS ]] ; then
|
|
||||||
read -r -a _ssh_additional_arguments <<< "$PULSEAUDIO_TCP_SSH_ADDARGS"
|
|
||||||
_ssh_arguments+=("${_ssh_additional_arguments[@]}")
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_dir="$HOME"/.config/pulseaudio-tcp
|
config_dir="$HOME"/.config/pulseaudio-tcp
|
||||||
config=$config_dir/config.inc.sh
|
config=$config_dir/config.inc.sh
|
||||||
|
|
||||||
|
@ -560,10 +516,11 @@ fi
|
||||||
##
|
##
|
||||||
# Main Program
|
# Main Program
|
||||||
|
|
||||||
for operation in "${operations[@]}" ; do
|
|
||||||
rv=0
|
rv=0
|
||||||
|
|
||||||
if [[ "$operation" != setup ]] ; then
|
if test "$operation" = setup ; then
|
||||||
|
info "Entering setup mode ..."
|
||||||
|
else
|
||||||
if ! test -e "$config" ; then
|
if ! test -e "$config" ; then
|
||||||
error "Configfile $config does not exist (use \"$0 setup\" first)."
|
error "Configfile $config does not exist (use \"$0 setup\" first)."
|
||||||
rv=1
|
rv=1
|
||||||
|
@ -597,9 +554,7 @@ for operation in "${operations[@]}" ; do
|
||||||
|
|
||||||
if [[ $rv -ne 0 ]] ; then
|
if [[ $rv -ne 0 ]] ; then
|
||||||
error "Preliminary checks failed, skipping operation."
|
error "Preliminary checks failed, skipping operation."
|
||||||
break
|
else
|
||||||
fi
|
|
||||||
|
|
||||||
case "$operation" in
|
case "$operation" in
|
||||||
setup)
|
setup)
|
||||||
do_setup
|
do_setup
|
||||||
|
@ -627,8 +582,6 @@ for operation in "${operations[@]}" ; do
|
||||||
rv=1
|
rv=1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
fi
|
||||||
[[ $rv -ne 0 ]] && break
|
|
||||||
done
|
|
||||||
|
|
||||||
exit "$rv"
|
exit "$rv"
|
||||||
|
|
|
@ -1,27 +1,34 @@
|
||||||
_pulseaudio_tcp_completions() {
|
_pulseaudio_tcp_completions() {
|
||||||
local \
|
local \
|
||||||
command_list \
|
command_list \
|
||||||
|
command_pattern \
|
||||||
commands \
|
commands \
|
||||||
cur \
|
cur \
|
||||||
option_list \
|
option_list \
|
||||||
options \
|
options \
|
||||||
word
|
word
|
||||||
|
|
||||||
options=( "--debug" "--help" "--no-gui" "--" )
|
options=( "--debug" "--help" "--no-gui" )
|
||||||
commands=( "start" "stop" "status" "setup" "restart" )
|
commands=( "start" "stop" "status" "setup" "restart" )
|
||||||
|
|
||||||
cur=${COMP_WORDS[COMP_CWORD]}
|
cur=${COMP_WORDS[COMP_CWORD]}
|
||||||
more_options=true
|
|
||||||
|
|
||||||
for word in "${COMP_WORDS[@]}" ; do
|
for word in "${COMP_WORDS[@]}" ; do
|
||||||
[[ $word = "$cur" ]] && continue
|
[[ $word = "$cur" ]] && continue
|
||||||
[[ $word = -- ]] && more_options=false
|
|
||||||
options=("${options[@]/$word}")
|
options=("${options[@]/$word}")
|
||||||
commands=("${commands[@]/$word}")
|
commands=("${commands[@]/$word}")
|
||||||
done
|
done
|
||||||
|
|
||||||
"$more_options" && option_list="${options[*]}"
|
option_list="${options[*]}"
|
||||||
|
|
||||||
|
printf -v command_pattern "%s|" "${commands[@]}"
|
||||||
|
command_pattern="(${command_pattern%?})"
|
||||||
|
|
||||||
|
if [[ ${COMP_WORDS[*]} =~ $command_pattern ]] ; then
|
||||||
|
command_list=""
|
||||||
|
else
|
||||||
command_list="${commands[*]}"
|
command_list="${commands[*]}"
|
||||||
|
fi
|
||||||
|
|
||||||
mapfile -t COMPREPLY < <( compgen -W "$option_list $command_list" -- "$cur")
|
mapfile -t COMPREPLY < <( compgen -W "$option_list $command_list" -- "$cur")
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue