Files
horror/scripts/ton.sh
2026-08-31 12:28:34 +02:00

87 lines
2.8 KiB
Bash
Executable File

#!/usr/bin/env bash
# Legt den Tonweg für den Stream an und räumt ihn wieder ab.
#
# Bluetooth-Ausgaben haben eine eigene, ungenaue Uhr und laufen mit 44,1 kHz.
# Nimmt OBS deren Monitor auf, wandert der Ton mit der Zeit vom Bild weg —
# nach fünf Minuten sind es Sekunden. Eine Null-Senke hängt an der Systemuhr
# und liefert 48 kHz, also genau das, was der Encoder erwartet.
#
# ton.sh auf Senke anlegen, zum Standard machen, Mithören einrichten
# ton.sh ab Standard zurückstellen, Senke entfernen
set -euo pipefail
SENKE="filmabend"
MERKER="/tmp/filmabend-vorheriger-ausgang"
# wpctl zeigt Beschreibungen, keine Knotennamen — die ID kommt aus pw-dump
id_von() {
pw-dump | python3 -c "
import json, sys
name = sys.argv[1]
for o in json.load(sys.stdin):
if o.get('info', {}).get('props', {}).get('node.name') == name:
print(o['id']); break
" "$1"
}
name_des_standards() {
wpctl inspect @DEFAULT_AUDIO_SINK@ 2>/dev/null |
sed -n 's/.*node\.name = "\([^"]*\)".*/\1/p' | head -1
}
case "${1:-auf}" in
auf)
# Zuerst lesen: WirePlumber macht eine frisch angelegte Senke sofort
# zum Standard, danach wäre der alte Ausgang nicht mehr zu erfahren
VORHER="$(name_des_standards)"
[ -n "$VORHER" ] && [ "$VORHER" != "$SENKE" ] && echo "$VORHER" > "$MERKER"
ZURUECK="$(cat "$MERKER" 2>/dev/null || true)"
if [ -z "$ZURUECK" ]; then
echo "Kein voriger Ausgang bekannt — bitte einmal 'scripts/ton.sh ab' laufen lassen."
exit 1
fi
if [ -z "$(id_von "$SENKE")" ]; then
pw-cli create-node adapter "{
factory.name=support.null-audio-sink
node.name=$SENKE node.description=Filmabend
media.class=Audio/Sink object.linger=true
audio.rate=48000 audio.position=[FL,FR]
}" > /dev/null
sleep 1
fi
# Damit du selbst weiter über dein gewohntes Gerät hörst
if ! pgrep -f "node.name=filmabend-mithoeren" > /dev/null; then
nohup pw-loopback -m '[FL FR]' \
--capture-props="stream.capture.sink=true target.object=$SENKE node.name=filmabend-mithoeren" \
--playback-props="target.object=$ZURUECK node.name=filmabend-ausgabe" \
> /dev/null 2>&1 &
sleep 1
fi
# Ab jetzt landet aller Ton in der Senke — und von dort bei dir und im Stream
wpctl set-default "$(id_von "$SENKE")"
echo "Ton läuft über die Senke Filmabend, du hörst weiter über $ZURUECK."
;;
ab)
ZURUECK="$(cat "$MERKER" 2>/dev/null || true)"
if [ -n "$ZURUECK" ]; then
ID="$(id_von "$ZURUECK")"
[ -n "$ID" ] && wpctl set-default "$ID"
fi
pkill -f "node.name=filmabend-mithoeren" 2>/dev/null || true
ID="$(id_von "$SENKE")"
[ -n "$ID" ] && pw-cli destroy "$ID" > /dev/null 2>&1 || true
rm -f "$MERKER"
echo "Ton zurück auf ${ZURUECK:-dein Gerät}."
;;
*)
echo "Aufruf: ton.sh auf|ab"
exit 1
;;
esac