Fix: Cannot find device „tun0“

Neulich beim VPN Aufbau gefunden, offensichtlich reicht es nicht mehr sein Netzwerk einzuschalten, das Kernelmodul tun zu laden, nein, man braucht noch mehr.

$ modprobe tun
$ ifconfig tun0 up
Cannot find device „tun0“

Lösung:

Mit Rootrechten „ tunctl -t tun0 -n “ aus, dann gehts wieder.

Unter Fedora müßt Ihr dazu ggf. noch das tunctl Paket installieren: „dnf install tunctl

GUI-Requester aus Bashscripten erzeugen

Schnell mal ein Bashscript zusammen gebastelt, daß einen kleinen Job erledigt, machen wohl viele von uns. Blöd ist, daß man das Script vom Desktop aus startet, ohne dem Script irgend etwas mitgeben zu können. Das wäre es doch toll, wenn man den Benutzer elegant fragen könnte, oder?

GUI-Requester aus Bashscripten erzeugen

Im konkreten Fall geht es um ein Script, daß die Tonausgabe eines Programms umschaltet. Die Grundlagen dazu findet Ihr hier:

Twinkle, Twinkle little PVA …

Damit wir den Ton eines Programms umschalten können, müssen wir erstmal wissen, welches Programm gemeint ist und da setzt unser kleines Script an. Da wir vom Desktop reden, wird das tonausgebende Programm ein Fenster offen haben, damit man es bedienen kann.

Jetzt haben wir ein Bashscript gestartet, daß irgendwie mitbekommen muß, welches Fenster denn gemeint ist. Dazu nutzen wir „xprop“ . Xprop erzeugt einen Mauszeiger mit dem man auf das Fenster klicken kann, von dem man alles wissen will, und ich meine echt alles! Das geht sogar soweit, das Defaulticon des Prozesses anzuzeigen, daß zu dem Fenster gehört 😀  Sehr selbst:

XKLAVIER_STATE(INTEGER) = 0, 1654415104
_GTK_EDGE_CONSTRAINTS(CARDINAL) = 85
_NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_FOCUSED
WM_STATE(WM_STATE):
window state: Normal
icon window: 0x0
_NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 31, 0
_NET_WM_DESKTOP(CARDINAL) = 0
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_FULLSCREEN, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW
WM_HINTS(WM_HINTS):
Client accepts input or input focus: True
Initial state is Normal State.
bitmap id # to use for icon: 0x420235a
bitmap id # of mask for icon: 0x4202360
window id # of group leader: 0x4200001
_GTK_THEME_VARIANT(UTF8_STRING) = „dark“
XdndAware(ATOM) = BITMAP
_NET_WM_ICON(CARDINAL) = Icon (48 x 48):

▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓░ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▒░ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓░ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▒ ░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▒░░░░░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒
░ ░
░░ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

_GTK_WINDOW_OBJECT_PATH(UTF8_STRING) = „/org/gnome/Terminal/window/3“
_GTK_APPLICATION_OBJECT_PATH(UTF8_STRING) = „/org/gnome/Terminal“
_GTK_UNIQUE_BUS_NAME(UTF8_STRING) = „:1.148“
_GTK_APPLICATION_ID(UTF8_STRING) = „org.gnome.Terminal“
_NET_WM_OPAQUE_REGION(CARDINAL) = 0, 0, 1920, 1021
WM_WINDOW_ROLE(STRING) = „gnome-terminal-window-00a05266-8865-460d-9efd-dd4e9d0164db“
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 69215064, 69215065
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x4202357
WM_CLIENT_LEADER(WINDOW): window id # 0x4200001
_NET_WM_PID(CARDINAL) = 7153
WM_LOCALE_NAME(STRING) = „de_DE.UTF-8“
WM_CLIENT_MACHINE(STRING) = „eve.resellerdesktop.de“
WM_NORMAL_HINTS(WM_SIZE_HINTS):
program specified minimum size: 359 by 70
program specified resize increment: 7 by 15
program specified base size: 16 by 26
window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = „gnome-terminal-server“, „Gnome-terminal“
WM_ICON_NAME(COMPOUND_TEXT) = „marius@eve:~ — xprop“
_NET_WM_ICON_NAME(UTF8_ST_NET_WM_PID(CARDINAL) = 7153RING) = „marius@eve:~ — xprop“
WM_NAME(COMPOUND_TEXT) = „marius@eve:~ — xprop“
_NET_WM_NAME(UTF8_STRING) = „marius@eve:~ — xprop“

Was wir davon für den Job brauchen, habe ich mal blau markiert. Da steht die PID( ProzessID ) des Programms, das das Fenster aufgemacht hat. Mit folgender Anweisung kann man das im Script auslesen:

pid=$(xprop | grep _NET_WM_PID | grep -o [0-9]*)

Das erste Grep besorgt uns die Zeile, das zweite Grep lässt nur unsere gesuchten Zahlen übrig. Damit haben wir einen Teil der Aufgabe gelöst. Teil Zwei besteht darin, das neue Ausgabegerät für das Programm zu ermitteln.

Damit Ihr versteht, was da als Argumente benutzt wird, ist ein Blick in den anderen Artikel hilfreich. Kurzfassung: Ich habe zwei Ausgänge: Lautsprecher und HDMI(Kopfhörer) .

Mit Zenity können wir beliebige GUI-Requester bauen und das ausgewählte Ergebnis auslesen. Vermutlich ist das Programm bei Euch schon vorinstalliert.

out=$(zenity –list –radiolist –text „Set audio output for window:“ –column „Select“ –column „Output“ FALSE „Lautsprecher“ FALSE „HDMI“ FALSE „Kopfhörer“ )

Das sieht in Real dann so aus:

Mit „–column“ gibt man an, welche Spalten man haben will, dann kommt die Liste der Optionen. Für ein Radiobutton, also eine Liste, wo man nur ein Element ausgewählt haben kann, sind die Optionen so aufgebaut:

FALSE/TRUE Elementname
FALSE/TRUE Elementname
FALSE/TRUE Elementname
FALSE/TRUE Elementname

Wobei TRUE vorausgewählt meint, und FALSE nicht ausgewählt. Im Bashscript stehen die Optionen einfach hintereinander. Hat man etwas ausgewählt, wird es vom Prozess einfach als Text ausgegeben:

[marius@eve ~]$ zenity –list –radiolist –text „Set audio output for window:“ –column „Select“ –column „Output“ FALSE „Lautsprecher“ FALSE „HDMI“ FALSE „Kopfhörer“
Kopfhörer
[marius@eve ~]$

Ich hatte Kopfhörer ausgewählt 😉 Jetzt noch den Prozessnamen:

pname=$( cat /proc/$pid/stat | awk ‚{print $2};‘ | grep -o [a-zA-Z]* )

bauen wir es zusammen:

#!/bin/bash

pid=$(xprop | grep _NET_WM_PID | grep -o [0-9]*)
out=$(zenity –list –radiolist –text „Set audio output for window:“ –column „Select“ –column „Output“ FALSE „Lautsprecher“ FALSE „HDMI“ FALSE „Kopfhörer“ )
pname=$( cat /proc/$pid/stat | awk ‚{print $2};‘ | grep -o [a-zA-Z]* )
pulse.out $pname $out

Fertig. Aber, mit Sonderzeichen im Prozessnamen wird es wohl Probleme geben.

Damit kann man jetzt ein Script starten, das lässt einen ein Fenster auswählen, dann fragt man nach der Tonausgabe und dann wechselt der Ton. Das geht natürlich viel einfacher, wenn man einen Sprachassistenten hat 😀

command:“schalte .* auf .* um“,“EXEC:pulse.outx:x%0x:x%1″

Damit kann man jeden namentlich korrekt erkannten Prozess auf jedes konfigurierte Ausgabegerät umlenken. Hört meine Wort: Das wird Eure Zukunft.

 

 

Twinkle, Twinkle little PVA …

„Boar, wie geil..“ war das Echo, als meine neueste Erweiterung für Carola im Familienkreis vorgestellt habe, also sollt auch Ihr daran teilhaben 🙂

Twinkle, Twinkle little PVA …

Bislang kam bei Carola, unserem Lieblings-Personal-Voice-Assistant, Jitsi beim Telefonieren zum Einsatz, weil es das brauchbarste SIP Programm war. Das hat sich radikal geändert, als Twinkle auf der Bildfläche erschien.

Die Oberfläche von Twinkle, daß mit zwei Leitungen auch mal eine Dreierkonferenz makeln kann, ist eher ernüchtern:

Main-UI von Twinkle.

Da Twinkle im Livebetrieb diese UI nicht offen haben muß, kann man das verschmerzen. Die UI von Jitsi ist klein, schön und kompakt, so wie man das von klassischen InstantMessangern erwartet. Bei Twinkle geht es aber hauptsächlich um SIP, über das man auch Nachrichten schicken kann, und cooles Aussehen nicht so wichtig 😉

Der schwierigste Teil von Twinkle ist seine Konfiguration, aber nur, wenn man den SIP-Providernamen falsch angibt. Merkt Euch mal: IMMER den Domainnamen angeben, also sipgate.de, fritz.box usw. NIE die IP!

Ok, jetzt haben wir ein funktionierendes SIP-Programm, was das mit Carola zu tun hat, dürfte Euch natürlich klar sein, man kann damit jemanden Anrufen. Das war natürlich der erste Test, also sagen wir Carola, wir wollen mit X sprechen, Carola sucht die Nummer raus, teilt das Twinkle mit und das ruft dann die Nummer an. Soweit hatten wir das schon mit Jitsi, wenn Ihr Euch erinnern mögt, steht auch so in der Default Config vom PVA drin.

Eigentlich nicht weiter spannend, dann können wir jetzt aufhören… Sekunde mal, das Telefon klingelt.

„Carola am Apparat“
„Wie war Ihr Name?“
„Müßten Sie das nicht wissen, Sie haben doch mich angerufen“
„ich will mit meiner Tochter sprechen“
„geht nicht, ist nicht da.“
„können sie ihr sagen, das ich angerufen habe“
„nein, kann ich sonstwie helfen?“

Wäre die Google Stimme noch etwas besser, wäre das Gespräch oben geeignet gewesen, einen Menschen zu täuschen. So aber ist es nur unsere neueste Errungenschaft: Carola nimmt aktiv das Telefonat an und spricht mit den Anrufenden \o/

Die für das Gespräch nötige Config sieht so aus:

reaction:“wie war ihr name“,““,“Mein Name ist %KEYWORD“
reaction:“wer ist da“,““,“Hier ist %KEYWORD. Was möchten Sie von mir?“
reaction:“wer ist da“,““,“Sollten Sie das nicht wissen, sie haben mich angerufen!“
reaction:“ich will mit [Haushaltsmitglied1] sprechen“,““,“der ist unterwegs mit seiner Tabletschlampe Anja“
reaction:“ich will mit [Haushaltsmitglied2] sprechen“,““,“tut mir leid, die ist nicht zu sprechen.“
reaction:“ich will mit|sprechen“,““,“Ist nicht da“
reaction:“ich will mit|sprechen“,““,“Die Person ist mir unbekannt“
reaction:“ich will mit|sprechen“,““,“Pech gehabt, nicht da“
reaction:“ich will mit|reden“,““,“kenn ich nicht“
reaction:“ich will mit|reden“,““,“Pech gehabt, nicht da“
reaction:“können sie eine nachricht“,““,“nein, die Funktion ist noch nicht eingebaut“
reaction:“können sie eine nachricht“,““,“das tonband ist defekt“
reaction:“können sie eine nachricht“,““,“rufen Sie einfach später nochmal an.“
reaction:“können|sie|sagen|das“,““,“rufen Sie einfach später nochmal an.“
reaction:“können|sie|sagen|das“,““,“nein, kann ich sonstwie helfen?“
reaction:“können|sie|sagen|das“,““,“nein, der mp3-rekorder ist defekt“

Das ist natürlich nur ein Teil. Vorher müssen wir noch ein paar coole Techniken benutzen, damit sich Carola und wer auch immer da anruft, unterhalten können.

Der Pulseaudio Part

War klar, oder? Ohne Pulseaudio geht so etwas nicht, weil man PA erzählen extern kann, wo welches Programm seinen Sound ausgeben soll. Jetzt muß ich etwas ausholen, denn ich habe zwei Audiogeräte im PC:

  1. Die Mainboard Lautsprecher
  2. Einen HDMI Monitor mit Köpfhörerausgang

Wie Ihr vielleicht wisst, gibt es zu jedem Ausgabegerät unter Pulseaudio auch die Möglichkeit einen Monitor davon als Eingabegerät zu verwenden. Ihr ahnt vermutlich jetzt, wo die Reise hingeht. Wir verdrahten die Ausgabe von Twinkle zur Aufnahme von Carola und umgekehrt.

Da Carola über gsay/say Ihre Sätze an den Lautsprecher schickt, ist es tatsächlich so, daß Twinkles Aufnahme auf den Monitor vom Mainboard geht und Carola kurzfristig das HDMI Gerät belauscht, auf dem Twinkle die Sachen ausgeben wird.

Der Scriptteil

Damit das klappt, braucht es zwei Bashscripte: pulse.out + pulse.in

pulse.out stellt die Ausgaben um, pulse.in die Aufnahmen. Die Scripte könnt Ihr hier finden:

https://github.com/Cyborgscode/Personal-Voice-Assistent/tree/main/plugins/twinkle

Zur Technik:

Schritt 1 – Die Sinkid finden, auf der ein Prozess seine Ausgaben macht

echo $( LANG=C pactl list sink-inputs | grep -e „Sink\ Input“ -e „node.name“)

Geht den Befehl wenn Musik läuft ein, da kommt das raus:

Sink Input #543 node.name = „qmmp“

LANG=C ist nötig, damit es eine definierte Sprache gibt, die parsebare Ergebnisse liefert. Sonst müßte man das Script auf alle Sprachen erweitern. Jetzt haben wir die SinkID von QMMP und müssen wir noch wissen wohin die Reise gehen soll:  pactl list sinks | grep „Name:“

kommt u.a. so ein Treffer: „alsa_output.pci-0000_0a_00.4.analog-stereo“ Das ist in meinem Fall, die normale Lautsprecherausgabe vom Mainboard. Jetzt noch in einer Anweisung zusammen bringen:

pactl move-sink-input 543 alsa_output.pci-0000_0a_00.4.analog-stereo

Damit ist QMMP auf die Lautsprecher gelegt. Jetzt als Befehl fürs Script: pulse.out qmmp default

Wenn Ihr die Scripte zu hause benutzen wollt, dann müßt Ihr die Aus/Eingabe-Gerätenamen anpassen.

Damit kann man jetzt schon neue Funktionen für Carola bauen:

command:“schalte auf kopfhörer“,“EXEC:pulse.outx:x{config:audioplayer:pname}x:xhdmi“
command:“schalte auf lautsprecher“,“EXEC:pulse.outx:x{config:audioplayer:pname}x:xdefault“
command:“schalte um auf kopfhörer“,“EXEC:pulse.outx:x{config:audioplayer:pname}x:xhdmi“
command:“schalte um auf lautsprecher“,“EXEC:pulse.outx:x{config:audioplayer:pname}x:xdefault“

replacements:“h d m i“,“hdmi“
replacements:“u s b“,“usb“

command:“schalte .* um auf kopfhörer“,“EXEC:pulse.outx:x%0x:xhdmi“
command:“schalte .* um auf lautsprecher“,“EXEC:pulse.outx:x%0x:xdefault“
command:“schalte .* auf .* um“,“EXEC:pulse.outx:x%0x:x%1″

Die ersten vier Zeilen schalten den Default-Audioplayer um. Das ist eine nette kurzversion des Befehls. Mit {config:audioplayer:pname} bekommen wir den konfigurierten Prozessnamen von, in dem Fall, qmmp. Damit ist klar, wen das Script umschalten soll.

Die letzten drei Befehle wiederum nehmen einen beliebigen Prozessnamen an und schalten diesen Prozess auf wiederum beliebige Geräte um. (Spart es Euch, das ist doppelt exploitsicher, egal wie oft Ihr da ein ; einfügen wollt, es wäre nur ein Argument, keine Bashanweisung UND versucht mal Semikolon über eine Spracheingabe als ; einbauen zu lassen 😀 ) Da kann man also auch firefox oder twinkle angeben.

Das alleine reicht aber noch nicht für den Trick, ist aber eine sehr wichtige Grundlage!

Die Twinkleanbindung

Jetzt stellt Euch mal die Frage: „Woher weiß der PVA, daß jemand anruft?“ Antwort: „Weiß er nicht.“

Folgerichtig muß Twinkle die Arbeit leisten und Carola andocken 🙂 Dazu brauchen wir das hier:

und dazu brauchen wir die zwei Script ( auch auf Github ) :

#!/bin/bash

echo „action=autoanswer“
echo „end“

sleep 2s
pulse.in „PipeWire ALSA [python3.10]“ hdmimonitor
pulse.in „PipeWire ALSA [twinkle]“ defaultmonitor
pulse.out „PipeWire ALSA [twinkle]“ hdmi
gsay „Hi, Carola am Apparat“

Die beiden ersten Anweisungen sind an Twinkle selbst, sofort abzuheben und nicht mehr auf das Script zu warten. An der Stelle kann man auch noch eine spezielle Behandlung für bestimmte Anrufer einbauen, in dem man auf die CallerID checkt, aber das brauchen wir nicht.

Wir warten jetzt 2 Sekunden, damit alle Sinks aktiv sind und unsere Pulse.in und Pulse.out Scripte Ihre Magie ausführen können.

Wenn das gespräch beendet wird, was Carola nicht beeinflussen kann, kommt das Gegenscript zum Einsatz:

#!/bin/bash

pulse.in „PipeWire ALSA [python3.10]“ usb
pulse.in „PipeWire ALSA [twinkle]“ usb
pulse.out „PipeWire ALSA [twinkle]“ default

echo „action=end“

Alles wird wieder auf normal umgestellt. Wenn wir da sind, können wir , in meinem Fall, über die Kopfhörer den Anrufer hören und über den Lautsprecher was Carola sagt. Das hat den Vorteil, daß wenn der Anrufer z.b. ein Programm mit Tonausgabe startet, er das auch hören kann, weil für alle anderen Programme außer Twinkle, hat sich nichts an der eingestellten Konfig geändert.

Jetzt seid Ihr dran

Ok, Freunde, an der Stelle überlasse ich Euch jetzt das Feld. Ich will ausgeklügelte Telefonreaktionsketten sehen, in denen ein Anrufer solange wie möglich am Telefon gehalten wird 🙂 Die besten kommen ins Github!