-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvcable.sh
More file actions
executable file
·141 lines (122 loc) · 5.13 KB
/
Copy pathvcable.sh
File metadata and controls
executable file
·141 lines (122 loc) · 5.13 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env bash
# =========================================================================
# vcable: Transparent Virtual Audio Cable Installer
# Architecture: Minimalist + Systemd Persistence + Auto Dependency
# Features: Daemon-Crash Resilient (Auto-restarts on PipeWire restart)
# =========================================================================
set -e
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${BLUE}[*] Starting vcable Installation...${NC}\n"
# Safety Warning
echo -e "${RED}======================================================================${NC}"
echo -e "${YELLOW}IMPORTANT PRE-INSTALLATION STEP:${NC}"
echo -e "Please close all applications currently using your microphone or"
echo -e "speakers (e.g., OBS Studio, Discord, Zoom, Spotify, Web Browsers)."
echo -e "The installation will restart your audio engine, which may cause"
echo -e "active audio applications to crash or lose sound if left open."
echo -e "${RED}======================================================================${NC}\n"
read -p "Press [ENTER] when all audio apps are closed, or [Ctrl+C] to abort..."
# Dependency Check & Auto-Install
echo -e "${YELLOW}>> Executing: command -v pactl${NC}"
if ! command -v pactl &> /dev/null; then
echo -e "${YELLOW}[!] 'pactl' is missing. The 'pulseaudio-utils' package is required.${NC}"
read -p " Do you want to install it now? (Requires sudo password) [Y/n]: " choice
case "$choice" in
y|Y|yes|Yes|"")
echo -e "${BLUE}[*] Detecting package manager...${NC}"
if command -v apt &> /dev/null; then
sudo apt update && sudo apt install -y pulseaudio-utils
elif command -v dnf &> /dev/null; then
sudo dnf install -y pulseaudio-utils
elif command -v pacman &> /dev/null; then
sudo pacman -S --noconfirm libpulse
else
echo -e "${RED}[!] Unsupported OS. Please install 'pulseaudio-utils' manually.${NC}"
exit 1
fi
echo -e "${GREEN}[✓] Dependency installed successfully!${NC}\n"
;;
*)
echo -e "${RED}[!] Installation aborted. Cannot proceed without dependencies.${NC}"
exit 1
;;
esac
else
echo -e "${GREEN}[✓] 'pactl' is already installed.${NC}\n"
fi
# Server Detection
echo -e "${YELLOW}>> Executing: pactl info | grep 'Server Name'${NC}"
SERVER=$(pactl info | grep "Server Name")
if [[ "$SERVER" == *"PipeWire"* ]]; then
SYS="pipewire"
echo -e "${GREEN}[✓] Detected: PipeWire${NC}\n"
elif [[ "$SERVER" == *"PulseAudio"* ]]; then
SYS="pulseaudio"
echo -e "${GREEN}[✓] Detected: PulseAudio${NC}\n"
else
echo -e "${RED}[!] Error: Unknown audio server.${NC}"; exit 1
fi
# Directory Setup
SCRIPT_DIR="$HOME/.local/bin"
SYSTEMD_DIR="$HOME/.config/systemd/user"
ROUTING_SCRIPT="$SCRIPT_DIR/vcable-bridge.sh"
SERVICE_FILE="$SYSTEMD_DIR/vcable.service"
echo -e "${YELLOW}>> Executing: mkdir -p $SCRIPT_DIR $SYSTEMD_DIR${NC}"
mkdir -p "$SCRIPT_DIR" "$SYSTEMD_DIR"
echo ""
# Generate Core Script
echo -e "${YELLOW}>> Generating $ROUTING_SCRIPT...${NC}"
if [ "$SYS" == "pipewire" ]; then
cat << 'EOF' > "$ROUTING_SCRIPT"
#!/usr/bin/env bash
pactl load-module module-null-sink media.class=Audio/Sink sink_name="VirtualSpeaker" sink_properties="device.description='Virtual-Speaker'"
pactl load-module module-null-sink media.class=Audio/Source/Virtual sink_name="VirtualMic" sink_properties="device.description='Virtual-Mic'" channel_map=front-left,front-right
sleep 2
pw-link VirtualSpeaker:monitor_FL VirtualMic:input_FL
pw-link VirtualSpeaker:monitor_FR VirtualMic:input_FR
EOF
elif [ "$SYS" == "pulseaudio" ]; then
cat << 'EOF' > "$ROUTING_SCRIPT"
#!/usr/bin/env bash
pactl load-module module-null-sink sink_name="VirtualSpeaker" sink_properties="device.description='Virtual-Speaker'"
pactl load-module module-remap-source source_name="VirtualMic" master="VirtualSpeaker.monitor" source_properties="device.description='Virtual-Mic'"
EOF
fi
echo -e "${YELLOW}>> Executing: chmod +x $ROUTING_SCRIPT${NC}"
chmod +x "$ROUTING_SCRIPT"
echo ""
# Generate Systemd Service (WITH SYMBIOTIC BINDING)
echo -e "${YELLOW}>> Generating $SERVICE_FILE...${NC}"
if [ "$SYS" == "pipewire" ]; then
BIND_TARGET="pipewire.service wireplumber.service"
else
BIND_TARGET="pulseaudio.service"
fi
cat << EOF > "$SERVICE_FILE"
[Unit]
Description=Virtual Audio Bridge ($SYS)
Requires=$BIND_TARGET
After=$BIND_TARGET
PartOf=$BIND_TARGET
[Service]
Type=oneshot
ExecStart=$ROUTING_SCRIPT
RemainAfterExit=yes
[Install]
WantedBy=default.target
EOF
echo ""
# Apply & Restart Services
echo -e "${YELLOW}>> Executing: systemctl --user daemon-reload${NC}"
systemctl --user daemon-reload
echo -e "${YELLOW}>> Executing: systemctl --user restart pipewire pipewire-pulse wireplumber${NC}"
systemctl --user restart pipewire pipewire-pulse wireplumber || true
sleep 1
echo -e "${YELLOW}>> Executing: systemctl --user enable --now vcable.service${NC}"
systemctl --user enable --now vcable.service &> /dev/null
echo -e "\n${GREEN}[✓] Installation Complete!${NC}"
echo -e "Virtual cables are now fully resilient. If the audio daemon crashes or restarts, the cables will auto-rebuild."