Wer gerne Musik hört und oftmals angerufen wird kennt sicherlich das Problem,
dass man die Musik immer leiser macht oder ausschaltet und nach dem Gespräch
wieder anschaltet. Einer der Gründe, wieso ich freie Telefonanlagen (wie zum
Beispiel asterisk
) so mag, ist, dass man dieses Problem nun lösen
kann. Ich hab’ das mit zwei einfachen Scripts und ein paar Einstellungen für
meinen MP3-Player cmus
erreicht.
In der folgenden Anleitung gehe ich also davon aus, dass cmus
oder
ein ähnlich funktionierender MP3-Player verwendet wird sowie dass
asterisk
auf einem separaten Rechner läuft (wenn nicht, kann man
sich den Webserver- und den Socket-Schritt sparen).
cmus’ Status speichern und abrufen
Da cmus
standardmäßig keine externe „now playing”-Anzeige bietet,
aber Scripts aufrufen kann, wenn sich der Status ändert, brauchen wir ein
kleines Script, welches den Status behält:
~/.cmus/status.sh:
#!/bin/sh
# Saves the cmus status
while test $# -ge 2
do
eval _$1='$2'
shift
shift
done
echo $_status > ~/.cmus/play_status/status
Um dieses Script aufrufen zu lassen, muss die Einstellung :set
status_display_program=/home/michael/.cmus/status.sh
getätigt werden in
cmus
. Außerdem muss das Verzeichnis
~/.cmus/play_status/
existieren.
Den Status über’s Netz abrufbar machen
Mithilfe deines Lieblingswebservers oder über eine beliebige andere Art (NFS,
FTP, Samba, …) kannst du nun die Datei ~/.cmus/play_status/status
im Netz verfügbar machen, damit der (asterisk-)Server erkennt, ob momentan
Musik läuft oder nicht (wenn diese nämlich nicht läuft und man den Pause-Befehl
an cmus
schickt, fängt dieser an zu spielen – genau das Gegenteil
würde also erreicht).
Ich hab’ das über einen apache
-Vhost gelöst, da
apache
ohnehin zum Testen auf meinem Rechner läuft:
<VirtualHost 192.168.1.23:2424> ServerAdmin none@localhost DocumentRoot /home/michael/.cmus/play_status/ CustomLog /var/log/apache2/cmus.access common ErrorLog /var/log/apache2/cmus.error <Directory /home/michael/.cmus/play_status/> Options FollowSymlinks Allow from all </Directory> </VirtualHost>
cmus über’s Netz steuerbar machen
Das mitgelieferte Programm cmus-remote
greift standardmäßig via
UNIX-Socket auf cmus
zu. Damit cmus
nun TCP-Sockets
verwendet, muss man es mit folgender Option starten (das kann man leider
(noch?) nicht fix einstellen):
cmus --listen 192.168.1.23:2525
Die IP-Adresse und den gewünschten Port natürlich gegebenenfalls ersetzen ;-).
Doch das war noch nicht alles: Bei Zugriff über TCP erhält man nun (zu recht!)
die Meldung, dass das – komplett ohne Authentifizierung – unsicher sei.
Mithilfe von :set passwd=foo
kann man das Passwort setzen, welches
die Gegenseite braucht, um cmus
fernsteuern zu können.
Scripts für eingehende Anrufe und aufgelegte Anrufe
Das Script für eingehende Anrufe holt sich via wget
den
cmus
-Status von meinem Rechner, hält (falls Musik läuft) den
momentanen Song an und merkt sich, dass er eingegriffen hat, indem er
/tmp/call_broke_song
anlegt.
~/.pbx/cmus-incoming.sh:
#!/bin/sh
# This should be called on an incoming call from asterisk
playstatus=$(wget -qO- http://192.168.1.23:2424/status)
[ $playstatus = "playing" ] && {
touch /tmp/call_broke_song
echo -e "foo\nplayer-pause" | nc -q0 192.168.1.23 2525
}
exit 0
Das Script für aufgelegte Anrufe ist genauso simpel: Es prüft, ob zuvor eingegriffen wurde, schaut nach, ob der Status noch immer auf Pause steht (falls man sich während des Telefongesprächs dafür entscheidet, die Musik via Stop ganz auszuschalten, könnte das nicht der Fall sein) und setzt sie dann fort.
~/.pbx/cmus-hangup.sh:
#!/bin/sh
# This should be called when the call is over from asterisk
[ -f /tmp/call_broke_song ] && {
rm /tmp/call_broke_song
playstatus=$(wget -qO- http://192.168.1.23:2424/status)
[ $playstatus = "paused" ] && {
echo -e "foo\nplayer-pause" | nc -q0 192.168.1.23 2525
}
}
exit 0
Hier sieht man übrigens auch, dass cmus-remote
gar nicht verwendet
wurde. Stattdessen kommt nc
zum Einsatz, welches einfach den Text
(Passwort und den entsprechenden Befehl in der nächsten Zeile) an den Socket
sendet, welchen wir vorhin in cmus
konfiguriert haben.
Vor und nach dem Anruf Scripts einbauen
Der Mechanismus basiert darauf, dass vor und nach einem Anruf, egal wie er endet, ein Script ausgeführt wird. Ich würde sagen, dass das eigentlich der schwierigste Teil der ganzen Installation war ;-).
Durch die Option g
hört asterisk nicht mit der Abarbeitung des
aktiven Kontexts auf, sondern führt die nachfolgenden Aktionen aus. Das gilt
gleichermaßen für angenommene und nicht beantwortete Anrufe, sodass man manuell
prüfen muss.
Außerdem springt asterisk (nach Angabe der j
-Option bei
Dial()
auf jeden Fall) zu Priorität + 101 im Dialplan, falls die
Leitung gerade belegt ist. Dort startet man üblicherweise die Mailbox, hier
muss aber auch unser Script aufgerufen werden.
Zu guter letzt wird man feststellen, dass der Kontext direkt beendet wird,
falls der Anrufer auflegt. Hier bearbeitet asterisk den Dialplan gar nicht
weiter – außer man definiert den Dialplan für die Extension h
(für
„hangup”).
So sieht ein solcher Dialplan dann aus:
extensions.conf:
[default]
exten => 23,1,System(/home/michael/.pbx/cmus-incoming.sh)
exten => 23,2,Dial(SIP/23,30,gj)
exten => 23,3,System(/home/michael/.pbx/cmus-hangup.sh)
exten => 23,4,GotoIf($[ ${DIALSTATUS} = "NOANSWER" ]?103)
exten => 23,5,Hangup()
exten => 23,103,System(/home/michael/.pbx/cmus-hangup.sh)
exten => 23,104,VoiceMail(b23)
exten => h,1,System(/home/michael/.pbx/cmus-hangup.sh)
I run a blog since 2005, spreading knowledge and experience for almost 20 years! :)
If you want to support my work, you can buy me a coffee.
Thank you for your support! ❤️