-
Notifications
You must be signed in to change notification settings - Fork 0
/
pipewireRemote
executable file
·114 lines (104 loc) · 3.46 KB
/
pipewireRemote
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#! /bin/bash
#
# Default socket
readonly pipeWireRunDir="/run/user/${UID}/pipewire-remote"
readonly pipeWireSocket="pipewire-0"
readonly pipeWireSocketPath="${pipeWireRunDir}/${pipeWireSocket}"
readonly pipeWirePort=5739
# Manager socket
readonly pipeWireManagerSocket="${pipeWireSocket}-manager"
readonly pipeWireManagerSocketPath="${pipeWireRunDir}/${pipeWireManagerSocket}"
readonly pipeWireManagerPort=5740
# Host selection
readonly pipeWireRemoteHost="${1}"
cleanup(){
# Nested loop to clean on both ports
for pidvar in SOCAT_PID1 SOCAT_PID2; do
if [ -n "${!pidvar}" ]; then
if ps "${!pidvar}" > /dev/null 2>&1; then
echo "Terminating socat process at PID ${!pidvar}"
kill "${!pidvar}"
else
echo "No socat process to terminate at PID ${!pidvar}"
fi
fi
done
# Kill the PIDs listening on our ports if launched by this script
if [ "${SSH_NONMANAGER_PORT}" == "True" ]; then
for ssh_pid in $(lsof -i tcp:${pipeWireManagerPort}\
|awk 'NR!=1 {print $2}'|uniq); do
echo "Killing SSH process at PID ${ssh_pid} for nonmanager port"
kill "${ssh_pid}"
done
fi
if [ "${SSH_MANAGER_PORT}" == "True" ]; then
for ssh_pid in $(lsof -i tcp:${pipeWirePort}\
|awk 'NR!=1 {print $2}'|uniq); do
echo "Killing SSH process at PID ${ssh_pid} for manager port"
kill "${ssh_pid}"
done
fi
}
wait_for_port() {
local port=$1
local max_attempts=5
local attempt=1
while ! nc -z localhost "${port}"; do
echo "Waiting for port ${port} to be available..."
sleep 1
attempt=$((attempt + 1))
if [[ "${attempt}" -gt "${max_attempts}" ]]; then
echo "Failed to connect after ${max_attempts} attempts."
cleanup
exit 1
fi
done
}
pipewire_connect(){
# Create the remote path, and populate it with lock files
mkdir -p "${pipeWireRunDir}"
touch "${pipeWireSocketPath}.lock"
touch "${pipeWireManagerSocketPath}.lock"
# Create SSH port forwards and ensure that the port is listening
if ssh -L ${pipeWirePort}:localhost:${pipeWirePort} \
-o ExitOnForwardFailure=yes \
-o BatchMode=yes \
"${pipeWireRemoteHost}" -fN; then
SSH_NONMANAGER_PORT="True"
# Wait for the SSH port forwards to be established
wait_for_port "${pipeWirePort}"
else
echo "SSH port forwarding failed at port ${pipeWirePort}"
exit 1
fi
if ssh -L ${pipeWireManagerPort}:localhost:${pipeWireManagerPort} \
-o ExitOnForwardFailure=yes \
-o BatchMode=yes \
"${pipeWireRemoteHost}" -fN; then
SSH_MANAGER_PORT="True"
# Wait for the SSH port forwards to be established
wait_for_port "${pipeWireManagerPort}"
else
echo "SSH port forwarding failed at port ${pipeWireManagerPort}"
exit 1
fi
# Listen on SSH port forwards, and redirect to a UNIX socket
socat UNIX-LISTEN:"${pipeWireSocketPath}",fork \
TCP:localhost:${pipeWirePort} &
SOCAT_PID1=${!}
echo "socat running at PID ${SOCAT_PID1}"
socat UNIX-LISTEN:"${pipeWireManagerSocketPath}",fork \
TCP:localhost:${pipeWireManagerPort} &
SOCAT_PID2=${!}
echo "socat running at PID ${SOCAT_PID2}"
}
# Trap SIGINT (Ctrl+C) to execute the cleanup function
trap cleanup SIGINT
# Connect to the remote pipewire server
pipewire_connect
# Run coppwr (in flatpak) against the remote sockets
flatpak run --filesystem="${pipeWireRunDir}" \
--env=PIPEWIRE_RUNTIME_DIR="${pipeWireRunDir}" \
io.github.dimtpap.coppwr
# Clean up at the end of script
cleanup