(gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Sound, Digitalkameras, TV+Video und Spiele.
fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 24.06.2020 21:03:31

Ich denke, ich habe weitgehend alles verdaut und bedanke mich nochmals für die kompetente und geduldige Hlfe! :hail:

Das sowas geht: bluetoothctl <<< "info ${BT_MAC[${i}]}" also ein Programm zu starten, dem man dann als Eingabe sein Unterprogramm nebst MAC in einer Variablen übergibt (was nicht mal als Parameterübergabe beim Programmstart funktioniert), ist zwar außerordentlich trick- und vor allem hilfreich, empfinde ich aber trotzdem als ziemlich schräg und warum man das jetzt mit "Here document/string" benennt, bleibt mir völlig unverständlich

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: (gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 25.06.2020 16:54:37

Hat Spaß gemacht, gerne.

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 02.07.2020 17:15:37

Eine Frage hätt' ich dann doch noch. Wenn ich das script in Verbindung mit vlc starte, siehe viewtopic.php?f=25&t=177914, wie beende ich es dann eigentlich? Oder geschieht das automatisch mit dem Beenden von VLC? Ich verlass' mich bis jetzt darauf, heißt: es scheint so zu sein, aber ob's wirklich so ist?

Ach ja, und noch 'ne Kleinigkeit: Ich bin unsicher, ob, um die letzten echos loszuwerden, ich in der Zeile

Code: Alles auswählen

pgrep "ecasound" | grep ${pid} &> /dev/null && kill ${pid} && echo "erledigt." || echo "?"
ab dem zweiten „&&“ einfach alles löschen, respektive via Doppelkreuz auskommentieren kann.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: (gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 02.07.2020 23:38:49

Alles inklusive dem && vor dem ersten echo muss weg

Code: Alles auswählen

pgrep "ecasound" | grep ${pid} &> /dev/null && kill ${pid}
Beim Schreiben des Skriptes bin ich davon ausgegangen, dass du es entweder in einem Terminal, mittels eines Startknopfes oder sogar einfach automatisch beim Anmelden startest.
Bei deiner Variante mit deinem eigenen Skript

Code: Alles auswählen

#!/bin/sh

vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0" &
sleep 5s
~/asoundrc-versuche/ecas-wahl3
läuft das ecasound-Skript mit ecasound solange weiter, wie das Skript läuft (und umgekehrt). Du kannst das auch einfach überprüfen indem du nach dem Beenden von vlc mit irgendeinem anderen Programm etwas über "hw:Loopback,0" oder "plughw:Loopback,0" abspielst – das sollte unverändert aus dem internern Lautsprecher oder den verbundenen Bluetoothgeräten tönen.

Du könntest jetzt an den Aufruf des ecasound-Skriptes noch ein & hängen, damit das ebenfalls im Hintergrund ausgeführt wird

Code: Alles auswählen

#!/bin/sh

vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0" &
sleep 5s
~/asoundrc-versuche/ecas-wahl3 &
aber dann kommt eventuell wieder die Eigenheit von vlc ins Spiel, das sich der Aufruf gleich nach dem Start wieder beendet (und nur ein bereits laufendes vlc fernsteuert).


Wie man elegant damit umgehen könnte, damit das ecasound-Skript sich erst beendet, wenn vlc beendet wird, weiß ich auch nicht. Meine erste Idee wäre zu prüfen ob vlc läuft:

Code: Alles auswählen

#!/bin/bash

vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0" &
sleep 5s
~/asoundrc-versuche/ecas-wahl3 &

while sleep 5s ; do
	pgrep -cxf vlc &> /dev/null || pgrep -cxf /usr/bin/vlc &> /dev/null || exit 0
done
So laufen vlc und das ecasound-Skript im Hintergrund. Die Schleife am Ende prüft alle 5 Sekunden ob vlc noch läuft und hält so dein Skript am Laufen.
Erst wenn vlc nicht mehr läuft beendet sich dein Skript und damit sollte auch das ecasound-Skript beendet werden. Übersieh bitte nicht, dass ich statt /bin/sh, die bash verwerndet habe. Ich versteh es zwar nicht, aber die Schleife funktioniert mit der /bin/sh nicht richtig.

Die 5 Sekunden Pause zwischen dem Start von vlc und dem des ecasound-Skripts sollten übrigens wirklich nicht notwendig sein.

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 03.07.2020 07:47:49

Beim Schreiben des Skriptes bin ich davon ausgegangen, dass du es entweder in einem Terminal [...] startest.
So bin ich auch vorgegangen. Beenden konnte ich das script (ecas-wahl3) auch in dieser Phase nur mit mit Strg+c und das auch nur, wenn's fehlerfrei lief.

Code: Alles auswählen

...
~/asoundrc-versuche/ecas-wahl3 &

while sleep 5s ; do
	pgrep -cxf vlc &> /dev/null || pgrep -cxf /usr/bin/vlc &> /dev/null || exit 0
done
Habe ich umgesetzt. Ecasound läuft weiter, sehe ich an den Console-Meldungen, wenn ich nach Beenden von vlc die GUI verlasse.

Nach deinen neuen Hinweisen auf Eigenheiten von vlc habe ich alle Tests so durchgeführt, dass ich nach jedem vlc-Lauf mich aus- und wieder eingeloggt habe (anders wusste ich ecasound bisher nicht totzukriegen) und dann wegen vlc auch noch rebootet habe.

Das ist mit einiger Sicherheit wohl keine sinnvolle Lösung, aber damit ist doch, denke ich, ausgeschlossen, dass bei einem neuen Test noch irgendetwas störend in die Suppe spucken könnte. Und so scheint's auch völlig zufriedenstellend zu funktionieren, ob mit oder ohne „&“ in

Code: Alles auswählen

~/asoundrc-versuche/ecas-wahl3
, ob mit oder ohne vlc-Kontrolle - bis auf das Beenden von ecasound.

edit:
nach dem Beenden von vlc sehe ich mit

Code: Alles auswählen

ps -e
Pozesse von ecas-wahl3 und ecasound. Beide kann ich mit killall ecas-wahl3/ecasound beenden, ecasound nur, wenn ich vorher ecas-wahl3 getötet habe.
Die Hinweise zur bash habe ich berücksichtigt, Beide Scripte benutzen den Link auf die dash nicht mehr.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: (gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 03.07.2020 23:21:25

Ok dann speichern wir eben die PID des ecasound-Skripts und töten das Skript am Ende explizit, ungefähr so (und sicherheitshalber mit ein paar Ausgaben):

Code: Alles auswählen

#!/bin/bash

vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0" &
sleep 5s

echo "Starte ecasound-script."
~/asoundrc-versuche/ecas-wahl3 &
EcaScriptPID=${!}

while sleep 5s ; do
	pgrep -cxf vlc &> /dev/null || pgrep -cxf /usr/bin/vlc &> /dev/null || exit 0
done

echo "Beende ecasound-script."
kill ${EcaScriptPID}

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: (gelöst) Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 04.07.2020 08:59:36

Funtioniert nicht.

Ich habe mein script, dahingehend geändert, dass ich statt „vlc "${1}" --aout alsa ...“ „vlc [Dateiname] --aout alsa ...“ eingetragen habe, (hoffe, der bash damit nicht zu nahe getreten zu sein, bzw. einen untauglichen Test kreiert zu haben. :wink: ), anders wüsste ich nicht, es im Terminal zu starten und ohne Terminal wären doch die beiden echos sinnlos - oder?

Hier die Meldungen, nach dem Beenden von vlc:

Code: Alles auswählen

...
QObject::~QObject: Timers cannot be stopped from another thread
neuer Schleifendurchgang, connected=2 und running=2...
überprüfe Bluetooth-Verbindungen: 2.
prüfe ob ecasound noch läuft: 2.
neuer Schleifendurchgang, connected=2 und running=2...
überprüfe Bluetooth-Verbindungen: 2.
...
die relevante ist vermutlich die in der 1. Zeile. Darauf zu reagieren weiß ich nicht.
Die Meldung

Code: Alles auswählen

echo "Beende ecasound-script."
erscheint nicht.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 04.07.2020 12:39:35

Das Starten im Terminal ohne die Anpassung wäre leicht

Code: Alles auswählen

~/mein/vlc-start-skript ~/meine/Videodatei
${1} ist dann im Skript ~/meine/Videodatei, aber so wie du es gemacht hast passt es schon.

Ob die erste Zeile die Ursache ist, weiß ich nicht – es ist jedenfalls eine Meldung von vlc und möglicherweise ist es ein Bug Debian Bugreport925220. Probier einmal aus ob unser Befehl zum Prüfen ob vlc läuft funktioniert, also folgenden Befehl im Terminal ausführen

Code: Alles auswählen

pgrep -cxf vlc || pgrep -cxf /usr/bin/vlc && echo "vlc läuft." || echo "vlc läuft nicht."
dann vlc normal starten, wieder den Befehl aufrufen
dann vlc beenden, wieder den Befehl ausführen
dann vlc über dein Skript starten und den Befehl aufrufen
und zuletzt noch einmal nach dem Beenden von vlc den Befehl ein letztes Mal aufrufen.
(Mein Verdacht ist, dass das Ergebnis beim letzten Schritt zeigt, dass vlc noch unerwartet weiterläuft.)

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 04.07.2020 16:32:50

Hmm, da müssten wir uns wohl zuvor darauf einigen, was wir unter normal verstehen wollen (Terminalstart, Dateimanagerstart ohne ecasound, tint2-Launcher, mit bluetooth ohne BT, ...etc

Hier schon mal überraschende Ergebnisse:
vlc via tint2-Starter gestartet. kein Video übergeben. pgrep-Befehl bei laufenden vlc ausgeführt. Meldung "vlc läuft nicht." 8O

Das gleiche mit vlc-Start via script und pgrep-Befehl bei laufendem vlc.

vlc ohne Video/Datei im Terminal gestartet:

Code: Alles auswählen

VLC media player 3.0.8 Vetinari (revision 3.0.8-0-gf350b6b5a7)
[000056000fe04100] vlcpulse audio output error: PulseAudio server connection failure: Connection refused
[000056000fd45170] main libvlc: VLC wird mit dem Standard-Interface ausgeführt. Benutzen Sie 'cvlc', um VLC ohne Interface zu verwenden.
[000056000fdd0290] main playlist: playlist is empty
die Meldung pulse betreffend hätte ich für nomal gehalten. In den Einstellungen steht Ausgabemodul auf „automatisch“

pgrep:

Code: Alles auswählen

1
vlc läuft.
vlc über's Menü beendet, Meldung im Terminal:

Code: Alles auswählen

QObject::~QObject: Timers cannot be stopped from another thread
Jetzt pgrep:

Code: Alles auswählen

0
0
vlc läuft nicht.
Immerhin! Aber wieso zweimal 0?

„normaler Start“ via Dateimanager (ohne ecasound). pgrep-Meldung im Terminal bei laufendem vlc:

Code: Alles auswählen

0
0
vlc läuft nicht.
8O

Verwirrend, das Ganze.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 04.07.2020 22:30:50

fischic hat geschrieben: ↑ zum Beitrag ↑
04.07.2020 16:32:50

Code: Alles auswählen

0
0
vlc läuft nicht.
Immerhin! Aber wieso zweimal 0?
[...]
Die Abfrage habe ich aus zwei zusammengebaut, es wird gefragt ob ein Programm vlc oder ein Programm /usr/bin/vlc läuft (in der Prozessliste steht abhängig davon wie der Prozess gestartet wurde entweder nur der Dateiname oder der komplette Pfad). Das funktioniert glaube ich deswegen nicht immer, weil in der Prozessliste, je nachdem wie vlc gestartet wurde, auch die abgespielte Datei vorkommt.

Einfacher und wohl zuverlässiger wäre es nur zu prüfen ob ein Prozess existiert, in dem vlc vorkommt. Funktioniert die Abfrage mit dem Befehl zuverlässig?

Code: Alles auswählen

pgrep -c vlc && echo "vlc läuft." || echo "vlc läuft nicht."

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 05.07.2020 12:28:10

Das script hat jetzt die Form:

Code: Alles auswählen

#!/bin/bash

vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0" &
echo "Starte ecasound-script."
~/asoundrc-versuche/ecas-wahl3 &
EcaScriptPID=${!}

while sleep 5s ; do
	pgrep -cxf vlc &> /dev/null || pgrep -cxf /usr/bin/vlc &> /dev/null || exit 0
done

echo "Beende ecasound-script."
kill ${EcaScriptPID}
Deine Versuchreihe habe ich mal so nummeriert:
1. dann vlc normal starten, wieder den Befehl aufrufen
2. dann vlc beenden, wieder den Befehl ausführen
3. dann vlc über dein Skript starten und den Befehl aufrufen
4. und zuletzt noch einmal nach dem Beenden von vlc den Befehl ein letztes Mal aufrufen.

Als „normalen Start“ habe ich mal angenommen: Linksklick auf das Video im Dateimanager xfe (xfe ist so konfiguiert, dass er beim Linksklick auf eine Datei diese mit einem von mir ihm angegebenen Programm, hier vlc öffnet).
Beendet habe ich vlc jeweils über das vlc-Menü
Beim vlc.Start via script habe ich deine Form benutzt:

Code: Alles auswählen

~/mein/vlc-start-skript ~/meine/Videodatei

Code: Alles auswählen

pgrep -c vlc && echo "vlc läuft." || echo "vlc läuft nicht."
habe ich jeweils im gesonderten Terminal ausgeführt.

hier die Ergebnisse

1.: 1 vlc läuft.
2.: 0 vlc läuft nicht
3.: 2 vlc läuft.
4.: 1 vlc läuft.

Je mehr ich probiert habe, desto durcheinander wurde ich. Nach dem Start des ecasound-scriptes sehe ich nur noch Meldungen dieses scriptes, keine mehr vom rufenden script. ich wollte mal irgend einen String nach „~/asoundrc-versuche/ecas-wahl3 &“ ausgeben lassen, was ja doch eigentlich hätte geschehen müssen, da wir ecas-wahl3 in den Hintergund geschickt haben? Ich habe aber im Terminal, in dem vlc+ecas gestartet wurde, nichts gesehen.
In diesem Zusammenhang und nicht wissend, ob überhaupt relevant: Ich vermute

Code: Alles auswählen

elif test ${running} -ne -1 ; then
		echo -n "beende laufendes ecasound: "
		pgrep "ecasound" | grep ${pid} &> /dev/null && kill ${pid} # && echo "erledigt." || echo "?"
		running=-1
dieser Teil von ecas-wahl3 wird nie angesprungen.

nach mehreren Stunden Rumprobiererei habe ich mich dann mal gefragt, warum wir eigentlich vlc in den Hintergrund schicken und vlc+ecas so umgebaut:

Code: Alles auswählen

#!/bin/bash

echo "Starte ecasound-script."
~/asoundrc-versuche/ecas-wahl3 &
EcaScriptPID=${!}
vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0"

echo "Beende ecasound-script."
kill ${EcaScriptPID}
Und schon läuft die Sache! Reproduzierbar, auch ohne meine Klimmzüge mit Aus-/Einloogen, Neustart

Im Anschluss habe ich noch das gemacht:

Code: Alles auswählen

thekla@t430:~$ ps -e | grep vlc
thekla@t430:~$ ps -e | grep ecas
 3441 pts/0    00:00:00 ecasound
Den Prozess von ecasound muss ich wohl auch noch killen. Der stört dann einen „normalen“ Aufruf von vlc. :mrgreen:

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 05.07.2020 13:07:49

Deine Lösung ist viel besser!
fischic hat geschrieben: ↑ zum Beitrag ↑
05.07.2020 12:28:10
[...]
4. und zuletzt noch einmal nach dem Beenden von vlc den Befehl ein letztes Mal aufrufen.
[...]
4.: 1 vlc läuft.
Das ist das Blöde an meiner Idee. Es könnte vlc selbst schuld sein oder auch nicht: Wenn dein vlc-startendes Skript irgendetwas mit vlc im Namen hat, schlägt meine Abfrage auch auf dein Skript an und glaubt das vlc läuft.
Genau das wollte ich zuerst mit der zweigeteilten Abfrage verhindern, aber die hat ja auch nicht funktioniert.

fischic hat geschrieben: ↑ zum Beitrag ↑
05.07.2020 12:28:10
Je mehr ich probiert habe, desto durcheinander wurde ich. Nach dem Start des ecasound-scriptes sehe ich nur noch Meldungen dieses scriptes, keine mehr vom rufenden script. ich wollte mal irgend einen String nach „~/asoundrc-versuche/ecas-wahl3 &“ ausgeben lassen, was ja doch eigentlich hätte geschehen müssen, da wir ecas-wahl3 in den Hintergund geschickt haben? Ich habe aber im Terminal, in dem vlc+ecas gestartet wurde, nichts gesehen.
Ja es werden alle Meldungen im Terminal ausgegeben, egal ob das Programm im Hintergrund läuft oder im Vordergrund.

fischic hat geschrieben: ↑ zum Beitrag ↑
05.07.2020 12:28:10
In diesem Zusammenhang und nicht wissend, ob überhaupt relevant: Ich vermute

Code: Alles auswählen

elif test ${running} -ne -1 ; then
		echo -n "beende laufendes ecasound: "
		pgrep "ecasound" | grep ${pid} &> /dev/null && kill ${pid} # && echo "erledigt." || echo "?"
		running=-1
dieser Teil von ecas-wahl3 wird nie angesprungen.
Der wird angesprungen und soweit ich mich erinneren haben wir das auch getestet, wenn während der Wiedergabe ein Bluetoothgerät dazukommt oder wegfällt.
Dann muss ecasound beendet und mit den richtigen Optionen neu gestartet werden. (Eleganter und möglich wäre es das bereits laufende ecasound zu steuern, aber das habe ich nicht hinbekommen.)

fischic hat geschrieben: ↑ zum Beitrag ↑
05.07.2020 12:28:10
Im Anschluss habe ich noch das gemacht:

Code: Alles auswählen

thekla@t430:~$ ps -e | grep vlc
thekla@t430:~$ ps -e | grep ecas
 3441 pts/0    00:00:00 ecasound
Den Prozess von ecasound muss ich wohl auch noch killen. Der stört dann einen „normalen“ Aufruf von vlc. :mrgreen:
Wow, ecasound läuft weiter obwohl ecas-wahl3 schon beendet ist?

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 05.07.2020 13:19:00

smutbert hat geschrieben:Der wird angesprungen und soweit ich mich erinnere haben wir das auch getestet, wenn während der Wiedergabe ein Bluetoothgerät dazukommt oder wegfällt.
Stimmt! Ich erinnere mich. Aber im aktuellen Zusammenhang habe ich meinen armen Kopf nicht noch zusätzlich mit BT belastet. :wink: Ich habe einfach einen einzigen Kopfhörer verbunden und benutzt.
smutbert hat geschrieben:Wow, ecasound läuft weiter obwohl ecas-wahl3 schon beendet ist?
Das geht mir schon tagelang durch den Kopf. Bei allen Recherchen zu ecasound bin ich nie über einen Hinweis gestolpert, wie das Teil „offiziell“ beendet wird. Liegt vielleicht auch daran, dass es hier vielleicht „missbräuchlich“ :wink: verwendet wird. Wie dem auch sei, scheint sich niemand einen Kopf zu machen, dass das wissenswert sein könnte. :P

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 05.07.2020 15:12:32

fischic hat geschrieben: ↑ zum Beitrag ↑
05.07.2020 13:19:00
Das geht mir schon tagelang durch den Kopf. Bei allen Recherchen zu ecasound bin ich nie über einen Hinweis gestolpert, wie das Teil „offiziell“ beendet wird. Liegt vielleicht auch daran, dass es hier vielleicht „missbräuchlich“ :wink: verwendet wird. Wie dem auch sei, scheint sich niemand einen Kopf zu machen, dass das wissenswert sein könnte. :P
Es ist nichts inoffizielles dabei ecasound mit kill zu beenden, so wie ich es auch im ecasound-Skript gemacht habe, genau in dem elif, das du gereade gepostet hast.
Für das Beendes des Skripts samt ecasound habe ich auf Anhieb keine einfacher Lösung parat, aber eine Notlösung, die du im vlc-Startskript unterbrigen könntest. Einfach am Ende noch einen Befehl hinzufügen, der alle laufenden ecasounds beendet

Code: Alles auswählen

[...]

echo "Beende ecasound-script."
kill ${EcaScriptPID}
killall ecasound
(Der Befehl ist im Paket Debianpsmisc, das du vermutlich eh installiert hast.)

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 05.07.2020 15:46:24

Es ist nichts inoffizielles dabei ecasound mit kill zu beenden
Wie ist's mit „Stil“? :P (Nicht ganz ernst gemeint und nicht an dich gerichtet.)

Deine Idee mit killall hatte ich schon selbst umgesetzt. Ich hätt's gerne über eine Abfrage, z.B. via

Code: Alles auswählen

pgrep ecasound
gemacht, aber da weiß ich wieder nicht, wie man abfängt, wenn pgrep den Prozess nicht findet, ergo nix zurückgibt.

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 05.07.2020 17:54:00

Eine Möglichkeit wäre so etwas

Code: Alles auswählen

if EcasoundPID=$(pgrep ecasound) ; then
	kill ${EcasoundPID}
fi
EcasoundPID=$(pgrep ecasound) weißt der Variable Ecasound als Wert die Ausgabe von pgrep zu und das ist die Liste der PIDs zu den ecasound-Prozessen. Gibt es keine ist der Exitstatus von pgrep ungleich 0 und das kill wird nicht ausgeführt.

Die Schwachstelle ist, dass es eben mehrere ecasound-Prozesse geben könnte und damit der Wert von $EcasoundPID nicht mehr nur eine gültige PID ist. Dann scheitert das ganze.
Anders lösen könnte man das indem man jedes Element der pgrep-Ausgabe durchgeht, also

Code: Alles auswählen

for EcasoundPID in $(pgrep ecasound) ; do
	kill ${EcasoundPID}
done
dann werden alle ecasound-Prozesse gekillt.

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 05.07.2020 19:09:48

Die Schwachstelle ist, dass es eben mehrere ecasound-Prozesse geben könnte und damit der Wert von $EcasoundPID nicht mehr nur eine gültige PID ist. Dann scheitert das ganze.
Das hatte ich schon im Kopf und meine Idee war, eben den Exitstatus zu prüfen und wenn der = 0 ist, dann ein

Code: Alles auswählen

killall ecasound
loszulassen. Ein solches killall sollte alle ecasound-Prozelle killen, wenn meine (flüchtige) Recherche nicht trügt. Aber wie man den exitstatus hier abfagt/operabel macht, weiß ich halt bei dieser hochmögenden :wink: Shell-Syntax nicht.

edit:
Vielleicht so:

Code: Alles auswählen

pgrep ecasound > /dev/null
status=${?}
if test ${status} -eq 0
        then
	killall ecasound
fi
:?:

Benutzeravatar
smutbert
Moderator
Beiträge: 8331
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von smutbert » 05.07.2020 19:46:19

Das sollte gehen, ist aber unnotwendig umständlich. Einerseits brauchst du den Exitstatus nicht in einer eigenen Variablen (status) speichern, wenn du ihn ohnehin gleich prüfen willst kannst du gleich direkt ${!} prüfen, aber selbst das ist ein Umweg.
if prüft genau den Exitstatus des Befehls, du brauchst also nicht einmal test:

Code: Alles auswählen

if pgrep ecasound > /dev/null ; then
	killall ecasound
fi

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 05.07.2020 22:18:46

Funktioniert! Keine unerwarteten Prozesse mehr gefunden.
Es geht halt nix über jemanden, der Shell-Syntax kann!!! Ich bin's nicht. Ich sagte ja, ich weiß nicht, wie man's (am besten) operabel macht.

Ich bedanke mich zum wiederholten Male ausdrücklich! :THX: :THX: :THX: Ich denke, damit ist der (abermalige) Monster-Thread wohl endgültig gelöst.

fischig
Beiträge: 3639
Registriert: 24.12.2019 12:25:08
Lizenz eigener Beiträge: MIT Lizenz

Re: Bluealsa mit simultaner Tonausgabe auf zwei Geräten

Beitrag von fischig » 06.07.2020 11:18:23

So, ich fass' dann mal zusammen, worum's in diesem langen Thread ging und zu welcher Lösung smutbert dann gekommen ist. (Meinen eigenen Beitrag dazu schätze ich als verschwindend gering ein.)

Es ging ursprünglich darum, auf einem stretch-System den Ton eines Videos fallweise über zwei Bluetooth-Kopfhörer gleichzeitig/simultan wiederzugeben. Im weiteren Verlauf wurde diese Problemstellung dahingehend erweitert, dass die Tonausgabe, je nachdem welche Tonausgabegeräte dem System gerade zur Verfügung stehen, fallweise automatisch umgeschaltet wird auf nur einen BT-Kopfhörer oder ausschließlich auf den Systemlautsprecher. Zum Einsatz kommen sollte ein bei Raspian entwickeltes/wiederbelebtes (Fremd-)Paket namens bluealsa (1) anstelle von Debianpulseaudio. Mir war wichtig, dass das voreingestellt eingerichtete Alsa von der Einrichtung nicht berührt wird.
Zur Einrichtung der BT-Lautsprecher/Kopfhörer wurde bluetoothctl benutzt.

Voraussetzungen
(zu installiernde Pakete, falls nicht vorhanden):
Debianalsa-utils
Debianbluez
Debianbluetooth
bluealsa (siehe (1))
Debianecasound
Debianprocps für das Kommando pgrep
Debianpsmisc (für die Kommandos kill, killall)

Das Kernelmodul bluetooth muss aktiv sein.
Das KernelModul snd_aloop muss aktiv sein (für die Einrichtung einer virtuellen Soundkarte)
bluealsa (das Fremdpaket) muss laufen. Ich habe das so in /etc/rc.local eingetragen.

Code: Alles auswählen

/usr/bin/bluealsa &
smutbert und ich haben nie vollständig geklärt, ob in dieser Zeile eine zusätzliche Option vonnöten, überflüssig oder störend ist, so dass sie so aussieht:

Code: Alles auswählen

/usr/bin/bluealsa --disable-hfp &
. Hier funktioniert die Zeile ohne Zusatz.

Wahrscheinlich gibt's noch ein paar andere notwendige Voraussetzungen, aber die erinnere ich gerade nicht. Wenn mich jemand informiert, trage ich's gerne nach.

Als erstes muss eine ~/.asoundrc-Datei (oder systemweit /etc/asound.conf) mit folgendem Inhalt (für den Betrieb der BT-Geräte) erstellt werden:

Code: Alles auswählen

pcm.btL1 {			# Lautsprecher-pcm der Namensteil btL1 ist frei wählbar, aber Vorsicht: der gewählte Namen wird in anderen Abschnitten benutzt)				
  type bluealsa			# Alsa-Plugin
  interface "hci0"		# vom Kernel eingerichtete BT-Schnittstelle, kann man mit bluetoothctl erfahren
  device "[00:01:02:03:04:05]"  		# MAC-Adresse des Lautsprechers/Kopfhörers
				# Kopfhörer)
  profile "a2dp"		# Bluetooth-Profil
}

pcm.btL2 {			# siehe oben
  type bluealsa			# Alsa-Plugin
  interface "hci0"		# siehe oben
  device "[MAC2]"		# siehe oben
  profile "a2dp"		# Bluetooth-Profil
}


# plug-Plugins, die an die Bluetoothgeräte weiterleiten

pcm.plugbtL1 {
	type plug
	slave {
		pcm "plug:btL1" # siehe oben: Kommentar zu pcm.btL1
	}
}

pcm.plugbtL2 {
	type plug
	slave {
		pcm "plug:btL2" # siehe oben: Kommentar zu pcm.btL2
	}
}
Als nächstes ist ein Bash-Script mit diesem Inhalt zu erstellen:

Code: Alles auswählen

#!/bin/bash

BT_MAC[1]="12:51:02:20:0F:E8"
BT_MAC[2]="FC:58:FA:84:9B:E2"
INTERVAL=5
BUFFER=2048 # mit dem Wert kann man spielen, je nachdem ob und wie viele underruns ecasound erzeugt, er muss aber eine Zweier-Potenz von 1024 sein

# Funktion zum Starten von ecasound mit einem Argument
# 0 -> Ausgabe über die eingebauten Lautsprecher
# 1 -> Ausgabe über plugbtL1
# 2 -> Ausgabe über plugbtL2
# 3 -> Ausgabe über plugbtL1 und plugbtL2
start_ecasound() {
	if test "${1}" = 0 ; then
		ecasound -b:${BUFFER} -i alsaplugin,1,1 -o alsaplugin,0 &> /dev/null &
	elif test "${1}" = 1 ; then
		ecasound -b:${BUFFER} -i alsaplugin,1,1 -o alsa,plugbtL1 &> /dev/null &
	elif test "${1}" = 2 ; then
		ecasound -b:${BUFFER} -i alsaplugin,1,1 -o alsa,plugbtL2 &> /dev/null &
	elif test "${1}" = 3 ; then
		ecasound -b:${BUFFER} -a:1,2 -i alsaplugin,1,1 -a:1 -o alsa,plugbtL1 -a:2 -o alsa,plugbtL2 &> /dev/null &
	fi
	echo ${!}
}

# Funktion, die prüft welche Bluetoothgeräte verbunden sind
# 0: keines
# 1: plugbtL1
# 2: plugbtL2
# 3: plugbtL1 und plugbtL2
check_device() {
	bt_count=0
	for i in ${!BT_MAC[@]} ; do
		bluetoothctl <<< "info ${BT_MAC[${i}]}" | grep "Connected: yes$" &> /dev/null && bt_count=$((${bt_count}+${i}))
	done
	echo ${bt_count}
}

# Hauptteil
# die Variable running speichert, welcher ecasound-Befehl gerade läuft, -1 bedeutet keiner,
# der Rest stimmt mit den Argumenten von von start_ecasound() überein
running=-1
while true ; do
	echo -n "überprüfe Bluetooth-Verbindungen: "
	connected=$(check_device)
	echo "${connected}."
	if test ${running} -eq ${connected}; then
		echo -n "prüfe ob ecasound noch läuft: "
		pgrep "ecasound" | grep ${pid} &> /dev/null || running=-1
		echo "${running}."
	elif test ${running} -ne -1 ; then
		echo -n "beende laufendes ecasound: "
		pgrep "ecasound" | grep ${pid} &> /dev/null && kill ${pid} # && echo "erledigt." || echo "?"
		running=-1
	fi

	if test ${running} -ne ${connected} ; then
		echo -n "starte ecasound: "
		pid=$(start_ecasound ${connected}) && running=${connected} # && echo "ok." || echo "nicht ok."
	fi
	sleep ${INTERVAL}
done
Ich nenn das jetzt mal „script1“

So, im Prinzip war's das schon. Ich habe als Video-Abspielprogramm vlc benutzt. Für smplayer habe ich ein dem folgenden analoges Procedere noch nicht hingekriegt.
Um die Voreinstellungen des Abspielprogramms nicht zu verändern kann man nach Script-Start vlc im Terminal so starten:

Code: Alles auswählen

vlc [dateiname] --aout alsa --alsa-audio-device "hw:Loopback,0"
Man hört den Ton dann (entsprechend der im script eingebauten „sleep“s) verzögert auf einem, beiden oder dem internen Lautsprecher. Das script wird mit Strg+c (evtl. mehrmals eingeben) beendet. ecasound läuft allerdings weiter und muss gesondert gekillt werden. Bei vlc kann man auch die Audio-Voreinstellungen so ändern, dass dauerhaft (bis zur Einstellungsänderung, versteht sich) der Ton über die virtuelle Loopback-Soundkarte läuft. In meinem Dateimanager (Debianxfe, aber das dürfte bei allen anderen GUI-Dateimanagern nicht anders sein) kann man mit Rechtsklick ein „Programm“ zum Öffnen der Datei starten. Dazu haben wir ein weiteres Bash-Script geschrieben, mit diesem Inhalt:

Code: Alles auswählen

#!/bin/bash

script1 &
EcaScriptPID=${!}
vlc "${1}" --aout alsa --alsa-audio-device "hw:Loopback,0"

echo "Beende ecasound-script."
kill ${EcaScriptPID}
if pgrep ecasound > /dev/null ; then
	killall ecasound
fi
Damit starte ich jetzt das Video durch den o.a. Rechtsklick und das war's dann. Mit dem Beenden von vlc wird am Ende des zuletzt dargestellten Scripts dann sowohl script1 als auch ecasound automatisch beendet. die voreingestellten Sound- und vlc-Einstellungen werden vom Programmlauf nicht berührt.
Wer mehr über die Wege und Irrwege zu dieser Lösung erfahren möchte, kann außer dem aktuellen Thread noch diese beiden durchstöbern:
viewtopic.php?f=25&t=177914
viewtopic.php?f=25&t=177012&hilit=bluealsa
viewtopic.php?f=25&t=177042&hilit=bluealsa

(1) http://archive.raspberrypi.org/debian/p ... /bluealsa/ Man kann das auch in der sources.list eintragen (deb http://archive.raspberrypi.org/debian/ stretch main ui), dann wird per apt automatisch die zum System passende Version installiert. so habe ich es gemacht, aber danach habe ich die Zeile sofort wieder auskommentiert, um nicht unbeabsichtigt Fremdpakte auf das System zu holen.

Antworten