104 lines
2.7 KiB
Bash
Executable File
104 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
### CONFIG ###
|
|
# Name of the virtual sink
|
|
SINK_NAME="discord_sink"
|
|
|
|
# Name of your real output device (auto-detected later)
|
|
REAL_OUTPUT=""
|
|
################
|
|
|
|
set -e
|
|
|
|
echo "=== Discord App-Audio Routing Script ==="
|
|
echo "This will route ONLY one chosen application's audio to Discord."
|
|
echo
|
|
|
|
SINK_INPUTS=$(pactl list short sink-inputs | awk '{print $1}')
|
|
|
|
if [[ -z "$SINK_INPUTS" ]]; then
|
|
echo "No audio streams detected. Make sure the target app is playing audio!"
|
|
exit 1
|
|
fi
|
|
|
|
i=1
|
|
declare -A ID_MAP
|
|
|
|
for ID in $SINK_INPUTS; do
|
|
CLIENT_ID=$(pactl list short sink-inputs | awk -v id="$ID" '$1 == id {print $3}')
|
|
CLIENT_NAME=$(pactl list short clients | awk -v cid="$CLIENT_ID" '$1 == cid {print $3}')
|
|
|
|
# Remove quotes around client names, if any
|
|
CLIENT_NAME=${CLIENT_NAME//\"/}
|
|
|
|
echo "$i) $CLIENT_NAME (sink-input $ID)"
|
|
ID_MAP[$i]=$ID
|
|
i=$((i+1))
|
|
done
|
|
|
|
echo
|
|
read -p "Select the number of the app to route to Discord: " CHOICE
|
|
echo
|
|
|
|
TARGET_ID=${ID_MAP[$CHOICE]}
|
|
|
|
if [[ -z "$TARGET_ID" ]]; then
|
|
echo "Invalid choice."
|
|
exit 1
|
|
fi
|
|
|
|
echo $TARGET_ID
|
|
|
|
# --- Detect real output device ---
|
|
echo "[*] Detecting your real output device..."
|
|
REAL_OUTPUT=$(pactl list short sinks | grep -E "RUNNING|IDLE" | head -n1 | awk '{print $2}')
|
|
|
|
if [[ -z "$REAL_OUTPUT" ]]; then
|
|
echo "Could not automatically detect real output device! Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
echo " -> Real output device: $REAL_OUTPUT"
|
|
echo
|
|
|
|
# --- Create virtual sink ---
|
|
echo "[*] Creating virtual sink '$SINK_NAME'..."
|
|
pactl load-module module-null-sink sink_name=$SINK_NAME sink_properties=device.description="Discord_Share_Audio" >/dev/null
|
|
|
|
# Virtual monitor name
|
|
MONITOR="${SINK_NAME}.monitor"
|
|
|
|
# --- Make virtual sink default ---
|
|
echo "[*] Setting virtual sink as default output..."
|
|
pactl set-default-sink $SINK_NAME
|
|
|
|
# --- Create loopback so you can hear things ---
|
|
echo "[*] Creating loopback so you hear the audio normally..."
|
|
LOOPBACK_ID=$(pactl load-module module-loopback source=$MONITOR sink=$REAL_OUTPUT latency_msec=1)
|
|
echo " -> Loopback module: $LOOPBACK_ID"
|
|
echo
|
|
|
|
echo "[*] Routing selected app (${TARGET_ID}) to $SINK_NAME..."
|
|
pactl move-sink-input "$TARGET_ID" "$SINK_NAME"
|
|
|
|
echo
|
|
echo "==========================================================="
|
|
echo "✔ Routing complete."
|
|
echo "Start Discord screen share now — it will capture ONLY this app."
|
|
echo
|
|
echo "When you're done, press ENTER to restore normal audio."
|
|
echo "==========================================================="
|
|
read -p ""
|
|
|
|
# --- Cleanup ---
|
|
echo "[*] Restoring your real default output..."
|
|
pactl set-default-sink $REAL_OUTPUT
|
|
|
|
echo "[*] Removing loopback..."
|
|
pactl unload-module "$LOOPBACK_ID"
|
|
|
|
echo "[*] Removing virtual sink..."
|
|
pactl unload-module module-null-sink
|
|
|
|
echo "✔ Done. Audio restored."
|