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

Sound, Digitalkameras, TV+Video und Spiele.
fischig
Beiträge: 3640
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 » 21.06.2020 10:57:08

Stört es, wenn bluetoothctl noch andere BT-MACs als die optional zu benutzenden kennt, auch wenn die zugehörigen Geräte ausgeschaltet sind?

Code: Alles auswählen

BT_MAC[1]="88:00:00:00:31:F0"
BT_MAC[2]="12:51:02:20:0F:E8"
INTERVAL=10
BUFFER=4096
Das sind vier Variablendeklarationen+Initialisierung - richtig?
(Da sie nicht mehr verändert werden, könnte man sie auch als Konstanten auffassen, aber Shells unterscheiden nicht (wie Pascal) zwischen Konstanten und Variablen - richtig?)

Ich bin nach deinem Vorschlag vorgegangen, beide Kopfhörer aus, erst script, dann video, kein Ton auf dem eingebauten Lautsprecher.

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 » 21.06.2020 12:45:11

Nein, stört nicht und ja, richtig.
Zwischen Variablen und Konstanten wird tatsächlich nicht unterschieden, aber Variablen, die ich nur am Beginn einmal setze (also die, die ich als Konstante verwende) benenne ich mit Großbuchstaben.

Hilft es etwas, wenn du in Zeile 15 die Ausgabe von ecasound von »-o alsahw,0« in »-o alsaplugin,0« änderst?
Gibt das Skript zu Beginn einmal "starte ecasound" und dann alle 10 Sekunden "prüfe ob ecasound noch läuft" aus?

fischig
Beiträge: 3640
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 » 21.06.2020 13:55:56

Nein, auch die Änderung in Zeile 15 bringt keinen Ton auf dem internen.
Nein, Meldungen des scriptes gibt es gar keine, weder vor noch nach Änderung von Zeile 15.
Spielt es eine Rolle aus welchem Unterverzeichnis im User-Home heraus das script gestartet wird (ich habe es ecas-wahl getauft)?

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 » 21.06.2020 15:49:25

Es ist egal von wo es gestartet wird und das Verhalten bei dir ist jetzt etwas verzwickt - ohne Bluetoothgeräte sollte das Skript bei dir genauso laufen wie bei mir und das tut es nicht.

Ich habe jetzt ein paar zusätzliche Ausgaben mit echo eingebaut, damit wir (hoffentlich) sehen bis wo es richtig läuft:
NoPaste-Eintrag41067

edit:
Das Paket Debianprocps hast du installiert?
(Das enthält den Befehl pgrep und das ist der einzige den ich verwende, von dem ich mir nicht ganz sicher bin, dass du ihn installiert hast.)

Es sollte genügen, wenn du nur das Skript ausführst und die Ausgabe nach mindestens 10 Sekunden Laufzeit postest oder beschreibst.

fischig
Beiträge: 3640
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 » 21.06.2020 17:02:10

Code: Alles auswählen

~/asoundrc-versuche$ ./ecas-wahl2
setzen der konstanten Variablen: erledigt.
definiere Funktion zum Starten von ecasound: erledigt.
definiere Funktion zum Prüfen der Bluetooth-Verbindung: erledigt.
neuer Schleifendurchgang, connected= und running=-1...
überprüfe Bluetooth-Verbindungen:
Er hängt beim Überprüfen der Bluetooth-verbindungen, aber die Zeile vorher erscheint mir schon merkwürdig. Sollte da nicht connected=0 statt connected= erscheinen?

Debianpprocps war und ist installiert.

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 » 21.06.2020 18:12:01

connected= stimmt nach dem Start noch, vor der ersten Überprüfung ist die Variable noch „leer“.

Nachdem es (für mich wieder einmal komplett) überraschend am Prüfen der Bluetoothverbindungen hängt: Was macht beispielsweise der Befehl

Code: Alles auswählen

bluetoothctl info "88:00:00:00:31:F0"
denn im Terminal?

fischig
Beiträge: 3640
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 » 21.06.2020 19:28:16

Jetzt habe ich mich so sehr bemüht, dass die Bezeichner stimmen, und dann doch wieder vergessen, die MACs in der neuen Script-Version zu kontrollieren. :evil:

Die von dir gepostete MAC gehörte zum alten Werbelautsprecher. In der .asoundrc sind jetzt nur noch die beiden Kopfhörer eingetragen:

Code: Alles auswählen

[NEW] Device FC:58:FA:84:9B:E2 Maginon BTH 55
[NEW] Device 12:51:02:20:0F:E8 L1
bluetoothctl info 88:00:00:00:31:F0 sollte dann für's Script unerheblich sein - oder?

Nach Korrektur der MACs im Script ergeben sich aber keine anderen Meldungen.

In /var/lib/bluetooth/00:1A:7D:DA:71:13 habe ich - auch via bluetotthctl - noch nichts „gelöscht“.

Code: Alles auswählen

$ bluetoothctl
[NEW] Controller 00:1A:7D:DA:71:13 BlueZ 5.43 [default]
[NEW] Device 30:C0:1B:72:63:8E JBL GO 2
[NEW] Device FC:58:FA:84:9B:E2 Maginon BTH 55
[NEW] Device 12:51:02:20:0F:E8 L1
[NEW] Device 88:00:00:00:31:F0 BT-SPEAKER
Für einen der beiden (nicht verbundenen) Kopfhörer bringt bluetoothctl:

Code: Alles auswählen

[bluetooth]# info FC:58:FA:84:9B:E2
Device FC:58:FA:84:9B:E2
	Name: Maginon BTH 55
	Alias: Maginon BTH 55
	Class: 0x260404
	Icon: audio-card
	Paired: yes
	Trusted: yes
	Blocked: no
	Connected: no
	LegacyPairing: no
	UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
	UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
	UUID: Advanced Audio Distribu.. (0000110d-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
	UUID: Handsfree                 (0000111e-0000-1000-8000-00805f9b34fb)

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 » 21.06.2020 20:20:28

Die Ausgabe würde schon passen und auch eine falsche Mac-Adresse erklärt nicht, dass die Abfrage einfach hängen bleibt. Es hilft leider auch nicht viel zu wissen, dass es funktioniert bluetoothctl zu starten und dann interaktiv im bluetoothctl-Prompt mit info die Informationen zu einem Bluetooth-Gerät anzeigen zu lassen.

Es geht wirklich um einen Befehl der Form

Code: Alles auswählen

bluetoothctl info "88:00:00:00:31:F0"
in der Bash und wie der sich verhält. Wenn er zB zwar die gewünschten Informationen ausgibt, sich aber nicht beendet, würde das das Verhalten des Skripts erklären.

fischig
Beiträge: 3640
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 » 21.06.2020 22:08:59

Das Verhalten entspricht in etwa deinen Erwartungen. Die Info zur MAC liefert er zwar nicht, aber bluetoothctl beendet sich auch nicht:

Code: Alles auswählen

$ bluetoothctl info "12:51:02:20:0F:E8"
[NEW] Controller 00:1A:7D:DA:71:13 BlueZ 5.43 [default]
[NEW] Device 30:C0:1B:72:63:8E JBL GO 2
[NEW] Device FC:58:FA:84:9B:E2 Maginon BTH 55
[NEW] Device 12:51:02:20:0F:E8 L1
[NEW] Device 88:00:00:00:31:F0 BT-SPEAKER
[bluetooth]#
Da wird dann wohl ein weiteres script fällig, wie ich das bei den Radiosendern schon hatte - richtig?

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 » 21.06.2020 22:14:13

Man lernt nie aus. Versuch es bitte noch einmal mit

Code: Alles auswählen

bluetoothctl -- info "12:51:02:20:0F:E8"
oder

Code: Alles auswählen

bluetoothctl <<< "info 12:51:02:20:0F:E8"

fischig
Beiträge: 3640
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 » 21.06.2020 22:26:03

same procedure

fischig
Beiträge: 3640
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 » 21.06.2020 22:27:44

Code: Alles auswählen

bluetoothctl <<< "info 12:51:02:20:0F:E8"
Bingo!!!

Code: Alles auswählen

$ bluetoothctl <<< "info 12:51:02:20:0F:E8"
[NEW] Controller 00:1A:7D:DA:71:13 BlueZ 5.43 [default]
[NEW] Device 30:C0:1B:72:63:8E JBL GO 2
[NEW] Device FC:58:FA:84:9B:E2 Maginon BTH 55
[NEW] Device 12:51:02:20:0F:E8 L1
[NEW] Device 88:00:00:00:31:F0 BT-SPEAKER
[bluetooth]# info 12:51:02:20:0F:E8
Device 12:51:02:20:0F:E8
	Name: L1
	Alias: L1
	Class: 0x240404
	Icon: audio-card
	Paired: yes
	Trusted: yes
	Blocked: no
	Connected: no
	LegacyPairing: no
	UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
	UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
	UUID: Advanced Audio Distribu.. (0000110d-0000-1000-8000-00805f9b34fb)
	UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
	UUID: Handsfree                 (0000111e-0000-1000-8000-00805f9b34fb)
	UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
[bluetooth]# quit
[DEL] Controller 00:1A:7D:DA:71:13 BlueZ 5.43 [default]

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 » 21.06.2020 22:33:35

Dann ändere doch bitte Zeile 42 (?) entsprechend in

Code: Alles auswählen

		bluetoothctl <<< "info ${BT_MAC[${i}]}" | grep "Connected: yes$" &> /dev/null && bt_count=$((${bt_count}+${i}))

fischig
Beiträge: 3640
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 » 21.06.2020 22:37:14

So in der Richtung hatte ich schon gedacht! Aber heute nicht mehr, du weißt, ich bin umständlich und langsam. :P

fischig
Beiträge: 3640
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 » 22.06.2020 10:50:59

Es funktioniert soweit. Ton kommt von intern, wenn kein BT-Lautsprecher verbunden ist. Es wird umgeschaltet, wenn beide BT-Geräte verbunden werden. Ist nur eines verbunden, gibt's keinen Ton mehr aus dem internen, aber auch nicht aus dem BT-Lautsprecher. 2. und 3. deiner Optionenliste:
1. kein Gerät verbunden: Wiedergabe über die eingebauten Lautsprecher
2. btL1 (88:00:00:00:31:F0) verbunden: Wiedergabe über plugbtL1
3. btL2 (12:51:02:20:0F:E8) verbunden: Wiedergabe über plugbtL2
4. beide Bluetooth-Geräte verbunden: Wiedergabe über plugbtL1 & plugbtL2
funktionieren noch nicht.

Hier mal einige Meldungen dazu:

Code: Alles auswählen

./ecas-wahl2
setzen der konstanten Variablen: erledigt.
definiere Funktion zum Starten von ecasound: erledigt.
definiere Funktion zum Prüfen der Bluetooth-Verbindung: erledigt.
neuer Schleifendurchgang, connected= und running=-1...
überprüfe Bluetooth-Verbindungen: 2.
starte ecasound: ok.
neuer Schleifendurchgang, connected=2 und running=2...
überprüfe Bluetooth-Verbindungen: 2.
prüfe ob ecasound noch läuft: -1.
starte ecasound: ok.
Ich komme erst gegen abend dazu, den Fehler selbst zu suchen. Ob ich ihn finde, weiß ich nicht in Anbetracht meiner rudimentären Shell-Syntax-Kenntnisse.

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 » 22.06.2020 12:58:24

Der Fehler muss im entsprechenden ecasound-Aufruf stecken – ich sehs mir an sobald ich kann. edit: oder noch besser probiere den Befehl in einem Terminal ohne Skript aus (ich dachte der hätte so schon funktioniert):

Code: Alles auswählen

ecasound -b:4096 -i alsaplugin,1,1 -o alsa,plugbtL2

fischig
Beiträge: 3640
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 » 22.06.2020 15:18:08

(ich dachte der hätte so schon funktioniert):
Soweit ich erinnere, haben wir das via pcm.plug... nie probiert. Es ging amfangs um BT überhaupt, und da gab's kein pcm.plug... und danach (mit pcm.plug...) immer um's simultane Betreiben zweier BT-Geräte.

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 » 22.06.2020 22:58:23

Habe jetzt gesucht, aber wirklich nichts gefunden. Dann habe mir das nur eingebildet. Ich versteh aber auch nicht warum die Wiedergabe über nur ein Bluetoothgerät nicht funktioniert, wenn es über beide funktioniert.
Deswegen fällt mir wieder nichts besseres ein als dich den Befehl ausprobieren zu lassen :)
Also am besten bei laufendem Video und mit verbundenen btL2

Code: Alles auswählen

ecasound -b:4096 -i alsaplugin,1,1 -o alsa,plugbtL2
(und poste bitte die Ausgabe)

fischig
Beiträge: 3640
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 » 23.06.2020 09:32:33

MAC für btL2: FC:58:FA:84:9B:E2
Das einfache ecasound-Kommando funktioniert, wie gewünscht:

Code: Alles auswählen

~$ ecasound -b:4096 -i alsaplugin,1,1 -o alsa,plugbtL2
**************************************************************************
*        ecasound v2.9.1 (C) 1997-2014 Kai Vehmanen and others    
**************************************************************************
(eca-chainsetup-parser) Setting buffersize to (samples) 4096.
(eca-chainsetup) Chainsetup "untitled-chainsetup"
(eca-chainsetup) NOTE: Real-time configuration, but insufficient privileges to utilize real-time scheduling (SCHED_FIFO). With small buffersizes, this may cause audible glitches during processing.
(eca-chainsetup) "rt" buffering mode selected.
(eca-chainsetup) Opened input "alsaplugin", mode "read". Format: s16_le, channels 2, srate 44100, interleaved.
(audioio_alsa) Warning! Period-size differs from current client buffersize.
(eca-chainsetup) Opened output "alsa", mode "write". Format: s16_le, channels 2, srate 44100, interleaved.
- [ Connected chainsetup: "untitled-chainsetup" ] ------------------------
- [ Controller/Starting batch processing ] -------------------------------
- [ Engine - Driver start ] ----------------------------------------------
^C- [ Controller/Batch processing finished (0) ] ---------------------------
- [ Engine exiting ] -----------------------------------------------------
(eca-control-objects) Disconnecting chainsetup:  "untitled-chainsetup".
thekla@t430:~$ 
Versuche ich das Gleiche mit dem Script, kommt das:

Code: Alles auswählen

1. $ ./ecas-wahl2
2. setzen der konstanten Variablen: erledigt.
3. definiere Funktion zum Starten von ecasound: erledigt.
4. definiere Funktion zum Prüfen der Bluetooth-Verbindung: erledigt.
5. neuer Schleifendurchgang, connected= und running=-1...
6. überprüfe Bluetooth-Verbindungen: 1.
7. starte ecasound: ok.
8. neuer Schleifendurchgang, connected=1 und running=1...
9. überprüfe Bluetooth-Verbindungen: 1.
10. prüfe ob ecasound noch läuft: -1.
11. starte ecasound: ok.
12. neuer Schleifendurchgang, connected=1 und running=1...
13. überprüfe Bluetooth-Verbindungen: 1.
14. prüfe ob ecasound noch läuft: -1.
15. starte ecasound: ok.
Die Zeilennummern habe ich mit LO erzeugt, die gehören nicht zur Meldung. Meines Erachtens läuft es bis Z.9 normal, aber dann aktiviert er merkwürdigerweise nicht den Lautsprecher, sondern beginnt wieder von vorne.
Soweit ich das Script mittlerweile verstehe, passiert der Fehler bei Z.6: Sollte da (Wenn btL2 verwendet wird) nicht eine „2“ statt der „1“ erscheinen.
Ich glaube, ich habe den Fehler: Die MACs im Script sind gegenüber der asoundrc vertauscht. Wenn ich das korrigiere, kommt der Ton auch via Script auf btL2
Weitere Tests heute abend.

fischig
Beiträge: 3640
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 » 23.06.2020 19:16:28

So, das war's dann. Umschalten funktioniert wie gewünscht. :THX: :THX: :THX:

Kann man das Intervall = 10 verkleineren? Bis wohin sollte es keine Probleme geben?

Und jetzt die Verständnisfragen:
BT_MAC ist als Array initialisiert?
if test "${1}" = 0 Was ist das für 'ne 1 in der Schweifklammer? Ich hätte gedacht, da wird der Wert von bt_count geprüft.

3x < was bedeutet das?

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 » 23.06.2020 23:37:42

Wow, es funktioniert? Kann ich fast nicht glauben.
Das Skript sollte nur wenig Resourcen verbrauchen, ich würde auch keine Probleme erwarten, wenn du das Interval auf 1 reduzierst. Vielleicht willst du dann allerdings die vielen Ausgaben entfernen. Weniger gesprächig würde das Skript so aussehen (noch mit den vertauschten Mac-Adressen): NoPaste-Eintrag41073

Ja, BT_MAC ist ein array.

Ja, wir wollten bt_count prüfen. Aber ich meine gelernt zu haben, dass es schlechter Stil wäre in einer Funktion direkt auf eine Variable zuzugreifen (nur für Konstanten ist es soweit ich weiß in Ordnung).

Stattdessen übergeben wir der Funktion start_ecasound den Wert von bt_count als Argument. Das passiert in dieser fiesen Zeile

Code: Alles auswählen

pid=$(start_ecasound ${connected}) && running=${connected} && echo "ok." || echo "nicht ok."
in dem Zusammenhang wichtig ist aber nur der Teil

Code: Alles auswählen

start_ecasound ${connected}
Das (erste) Argument steht dann in der Funktion als Variable mit dem Namen 1 zur Verfügung.
Die geschweiften Klammern sind nur eine mögliche Schreibweise für Variablen ${1} ist dasselbe wie $1 genauso wie $bt_count dasselbe ist wie ${bt_count} oder $connected und ${connected}. Mit den geschweiften Klammern ist es nur immer eindeutig, wo der Name der Variable endet.



Das <<< habe ich vorher auch nicht gekannt. Es bedeutet lediglich, dass der nachfolgende String ("info ${BT_MAC[${i}]}") als Eingabe für das interaktive bluetoothctl verwendet wird.

fischig
Beiträge: 3640
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 09:16:21

Ok, ich glaube "${1}" ansatzweise nachvollziehen zu können.

Warum steht hinter hinter dem durch check_device eingeleiteten Abschnitt eine leere Klammer?

Was die nach links gerichtete Spitzklammer angeht: Ich meine zwischenzeitlich herausgefunden zu haben, dass damit eine Eingabe „umgelenkt“ wird. Das deckt sich mit deiner Erklärung. Aber warum dreimal diese Klammer? Gibt's dafür einen Begriff, nach dem man im Netz suchen kann?

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 » 24.06.2020 10:33:24

< wäre eine normale Eingabeumleitung:

Code: Alles auswählen

bluetoothctl < datei
würde den Inhalt der Datei »datei« als Eingabe an bluetoothctl schicken.


<< wäre ein zu unserem Fall sehr ähnliches „Here Document“. Das sähe in etwa so aus

Code: Alles auswählen

bluetoothctl <<EOF
...
...
EOF
wobei alles was zwischen den beiden EOF als Eingabe an bluetoothctl geht. (EOF ist allerdings willkürlich gewählt, man könnte stattdessen auch ein ! oder etwas anderes schreiben.)


<<<: Das was wir gemacht haben nennt man analog dazu „Here String“ und drei < sind es vermutlich nur, weil < und << schon für die beiden üblicheren Eingabeumleitungen belegt waren.
(Wie gesagt ich habe das vorher auch nicht gekannt.)
fischic hat geschrieben: ↑ zum Beitrag ↑
24.06.2020 09:16:21
Warum steht hinter hinter dem durch check_device eingeleiteten Abschnitt eine leere Klammer?
Weil die Bash ein bisschen komisch ist. In der bash gibt es zwei gleichwertige Möglichkeiten Funktionen zu definieren, so wie wir es gemacht haben

Code: Alles auswählen

meine_funktion() {
	...
	...
}
und

Code: Alles auswählen

function meine_funktion {
	...
	...
}
Die Klammern bei der ersten Variante sollen wohl andeuten, dass man Argumente übergeben kann.

fischig
Beiträge: 3640
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 12:28:45

(es) gibt zwei gleichwertige Möglichkeiten Funktionen zu definieren
Dachte ich mir, und mit echo $(tb_count) als letztem Kommando wird dann bt_count stillschweigend zum Funktionsergebnis von check_device(). (Meine ich mal indirekt bei Meillo gelernt zu haben, als es um die BT-Tonausgabe für mplayer ging. In pascal müsste ich sowas explzit definieren mit z.B.

Code: Alles auswählen

check_device=bt_count
Ich war mir nicht sicher ob, die leeren Klammern in Shell/Bash-Syntax sozusagen die Bezeichner für „Funktion“ sind.)

Ich vermag mir nichts unter einem „Hier Dokument/String“ vorzustellen.
Konkret läuft's in unserem Beispiel wohl darauf hinaus, dass vom bluetoothctl Kommando

Code: Alles auswählen

info MAC
nur die Zeile mit "Connected yes" erfasst wird und im Falle, dass diese Zeile gefunden wird, die Variable bt_count auf den Wert des Schleifenzählers gesetzt wird, mit dem sie gefunden wird.

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 » 24.06.2020 16:17:30

Fangen wir mit

Code: Alles auswählen

for i in ${!BT_MAC[@]} ; do
an. BT_MAC ist wie du schon richtig festgestellt hast ein Array, das bei uns aus zwei Elementen besteht BT_MAC[1] und BT_MAC[2]. Das @ in BT_MAC[@] steht für alle vorhandenen Elemente.
Dann ist da aber noch das Rufzeichen und das besagt, dass wir nicht die eigentlichen Elemente sondern deren Indizes, bei uns 1 und 2 wollen. ${!BT_MAC[@]} bedeutet so wie wir BT_MAC gesetzt haben. also schlicht "1 2". Die for-Schleife wird demzufolge mit i=1 und i=2 ausgeführt.



Als nächstes

Code: Alles auswählen

bluetoothctl <<< "info ${BT_MAC[${i}]}" | grep "Connected: yes$" &> /dev/null && bt_count=$((${bt_count}+${i}))
Da haben wir den Befehl mit dem Here String

Code: Alles auswählen

bluetoothctl <<< "info ${BT_MAC[${i}]}"
${BT_MAC[${i}]} ist das i-te Element von BT_MAC, also etwa 12:51:02:20:0F:E8
Das ganze mit dem here document und here string ist einfach eine Möglichkeit, einen Text (oder einen beliebigen anderen Inhalt) im Skript unterzubringen, den man sonst als eigene Datei zur Verfügung stellen müsste.
Ein eigenes Skript in bluetoothctl zu schreiben wäre für einen einzigen bluetoothctl-Befehl etwas unpraktisch, also übergeben wir den String "info ${BT_MAC[${i}]}" mit <<< an bluetoothctl, ganz so als würden wir beispielsweise „info 12:51:02:20:0F:E8“ mit der Tastatur eingeben.

Mit dem Pipe-Symbol | wird die Ausgabe eines Befehls als Eingabe auf den darauffolgenden weitergereicht. Die Ausgabe von bluetoothctl wird also mit grep nach einem bestimmten String durchsucht

Code: Alles auswählen

... | grep "Connected: yes$"
Das $ steht für das Zeilenende (das ist nur eine, in diesem Fall nicht notwendige, zusätzliche Bedingung). grep gibt nur Zeilen aus in denen der Suchstring vorhanden ist, aber weil wir an der Ausgabe der Zeile gar nicht interessiert sind, habe ich die Ausgabe ins digitale Nirvana (»/dev/null«) umgeleitet.

Code: Alles auswählen

... | grep "Connected: yes$" &> /dev/null
Statt an der Ausgabe orientieren wir uns am exit-Code von grep. Der ist nur 0, wenn etwas gefunden wurde. Dafür ist dann das && da:

Code: Alles auswählen

... && bt_count=$((${bt_count}+${i}))
Das führt den darauffolgenden Befehl nur aus, wenn der exit-Code des vorigen gleich 0 ist.
Nur wenn grep den Suchstring ("Connected: yes$") findet, addieren wir zur Variablen bt_count den Wert von i. Daraus folgt dann die Zuordnung
0...kein BT-Gerät
0+1=1...BT-Gerät Nummer eins
0+2=2...BT-Gerät Nummer zwei
0+1+2=3...beide BT-Geräte


Das letzte mit dem Funktionsergebnis sieht so aus:
In der Bash liefern Funktionen eigentlich kein Ergebnis. Man kann, wie vorhin grep, einen Wert als exit-Status sozusagen übergeben, dann hätten wir am Ende

Code: Alles auswählen

	exit ${bt_count}
schreiben müssen. Der exit-Code muss allerdings 0 oder eine natürliche Zahl bis maximal 255 sein.
Stattdessen geben wir mit echo ganz normal den Wert von bt_count aus. Im Terminal ausgeführt würde der Wert von bt_count einfach am Bildschirm ausgegeben.
Wir rufen die Funktion aber folgendermaßen auf

Code: Alles auswählen

connected=$(check_device)
Dabei wird check_device aufgerufen und die Ausgabe von check_device in der Variablen connected gespeichert.
Zuletzt geändert von smutbert am 25.06.2020 16:54:49, insgesamt 1-mal geändert.

Antworten