update
This commit is contained in:
1
Makefile
1
Makefile
@@ -57,6 +57,7 @@ stream: mtx
|
|||||||
|
|
||||||
stream-stop:
|
stream-stop:
|
||||||
-@pkill -f "obs --profile filmabend" 2>/dev/null
|
-@pkill -f "obs --profile filmabend" 2>/dev/null
|
||||||
|
-@scripts/ton.sh ab
|
||||||
@echo "OBS beendet."
|
@echo "OBS beendet."
|
||||||
|
|
||||||
# ── Datenbank hin und her (lokal ausführen) ───────────────────────────────────
|
# ── Datenbank hin und her (lokal ausführen) ───────────────────────────────────
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ if ! timeout 3 bash -c "</dev/tcp/${ZIEL}/1935" 2>/dev/null; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
scripts/ton.sh auf
|
||||||
|
|
||||||
mkdir -p "$P" "$BASIS/scenes"
|
mkdir -p "$P" "$BASIS/scenes"
|
||||||
|
|
||||||
# Sendeziel jedes Mal neu schreiben — es hängt am Argument
|
# Sendeziel jedes Mal neu schreiben — es hängt am Argument
|
||||||
@@ -56,16 +58,18 @@ BaseCY=1080
|
|||||||
OutputCX=1920
|
OutputCX=1920
|
||||||
OutputCY=1080
|
OutputCY=1080
|
||||||
FPSType=0
|
FPSType=0
|
||||||
FPSCommon=30
|
FPSCommon=60
|
||||||
|
|
||||||
[Output]
|
[Output]
|
||||||
Mode=Simple
|
Mode=Simple
|
||||||
|
|
||||||
[SimpleOutput]
|
[SimpleOutput]
|
||||||
VBitrate=6000
|
VBitrate=9000
|
||||||
ABitrate=160
|
ABitrate=160
|
||||||
StreamEncoder=x264
|
StreamEncoder=x264
|
||||||
Preset=veryfast
|
Preset=veryfast
|
||||||
|
UseAdvanced=true
|
||||||
|
x264Settings=keyint=60 min-keyint=60 scenecut=0 bframes=0
|
||||||
|
|
||||||
[Audio]
|
[Audio]
|
||||||
SampleRate=48000
|
SampleRate=48000
|
||||||
@@ -92,7 +96,7 @@ if [ ! -f "$BASIS/scenes/$PROFIL.json" ]; then
|
|||||||
{
|
{
|
||||||
"id": "pulse_output_capture",
|
"id": "pulse_output_capture",
|
||||||
"name": "Ton",
|
"name": "Ton",
|
||||||
"settings": {},
|
"settings": {"device_id": "filmabend.monitor"},
|
||||||
"versioned_id": "pulse_output_capture"
|
"versioned_id": "pulse_output_capture"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
86
scripts/ton.sh
Executable file
86
scripts/ton.sh
Executable file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/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
|
||||||
Reference in New Issue
Block a user