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)
Did you like this post? Subscribe to this blog’s RSS feed to not miss any new posts!
I run a blog since 2005, spreading knowledge and experience for over 20 years! :)
If you want to support my work, you can buy me a coffee.
Thank you for your support! ❤️