Voraussetzungen & Systemüberblick
Das Skript whisper_vermittlung.py läuft als Asterisk AGI-Prozess.
Eingehende Audiodaten (WAV) werden von Whisper transkribiert;
das Ergebnis (Nebenstellen-Nummer oder Name) wird als AGI-Variable zurückgegeben.
/opt/ und /etc/asterisk/.
Folgende Komponenten werden installiert:
- openai-whisper – Spracherkennungsmodell
- gTTS – Google Text-to-Speech für Bestätigungsansagen
- torch – PyTorch (Whisper-Backend, CPU-only reicht)
- sox – Audio-Konvertierung (WAV ↔ Telefon-Format)
- ffmpeg – Whisper-interne Audioverarbeitung
Systemvorbereitung
Als root einloggen und das System aktualisieren:
# Als root arbeiten
sudo -i
# System aktualisieren
apt update && apt upgrade -y
# Benötigte Systempakete
apt install -y \
python3-pip \
python3-venv \
python3-dev \
ffmpeg \
sox \
libsox-fmt-mp3 \
git \
curl
libsox-fmt-mp3 wird benötigt, damit sox MP3-Dateien (gTTS-Output)
in das Asterisk-WAV-Format konvertieren kann.
Whisper installieren
Whisper wird als root systemweit über pip installiert.
PyTorch (CPU-Version) wird als Abhängigkeit automatisch mitgezogen.
Dies dauert je nach Verbindung 5–15 Minuten.
# Whisper + alle Python-Abhängigkeiten als root installieren
pip3 install \
openai-whisper \
gtts \
torch \
torchvision \
torchaudio \
--break-system-packages
# Alternativ nur CPU-PyTorch (deutlich kleiner, ausreichend):
pip3 install openai-whisper gtts --break-system-packages
pip3 install torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/cpu \
--break-system-packages
--break-system-packages ist zwingend erforderlich,
da es sonst zu einem externally-managed-environment-Fehler kommt.
Als root ist dies unproblematisch.
Whisper-Modell herunterladen
Das Skript erwartet das Modell unter /opt/whisper-models/base.pt.
Das base-Modell (ca. 145 MB) ist ein guter Kompromiss zwischen
Genauigkeit und Geschwindigkeit auf älterer Hardware.
# Zielverzeichnis anlegen
mkdir -p /opt/whisper-models
# Modell direkt mit Python herunterladen und in Zielverzeichnis speichern
python3 -c "
import whisper, shutil, os
# Lädt nach ~/.cache/whisper/ – danach verschieben
m = whisper.load_model('base')
src = os.path.expanduser('~/.cache/whisper/base.pt')
dst = '/opt/whisper-models/base.pt'
shutil.copy2(src, dst)
print('Modell kopiert nach', dst)
"
# Alternativ: direkt mit wget (offizieller Download-Link)
wget -O /opt/whisper-models/base.pt \
https://openaipublic.azureedge.net/main/whisper/models/ed3a0b6b1c0edf879ad9b11b1af5a0e6ab5db9205f891f668f8b0e6c6326e34e/base.pt
# Berechtigungen setzen (Asterisk-User muss lesend zugreifen)
chmod 644 /opt/whisper-models/base.pt
chown root:root /opt/whisper-models/base.pt
Verfügbare Modelle
Falls bessere Erkennungsqualität gewünscht ist (auf leistungsfähiger Hardware):
tiny– 39 MB, schnellst, ausreichend für klare Sprachebase– 145 MB, empfohlen für dieses Projektsmall– 461 MB, deutlich bessere Erkennungmedium– 1,5 GB, sehr gut, benötigt mehr RAM
Für andere Modelle in whisper_vermittlung.py den Pfad MODELL_PFAD anpassen.
Python-Abhängigkeiten prüfen
Alle direkt im Skript verwendeten Module und ihr Status:
# Installierte Pakete überprüfen
python3 -c "
import sys, subprocess
pkgs = ['whisper', 'gtts', 'torch']
for p in pkgs:
try:
__import__(p)
print(f' ✓ {p}')
except ImportError:
print(f' ✗ {p} FEHLT')
"
# Übersicht aller installierten Versionen
pip3 show openai-whisper gtts torch 2>/dev/null | grep -E "^Name|^Version"
Folgende Module sind Python-Standardbibliothek und müssen nicht extra installiert werden:
sys,os,json,subprocess– immer verfügbar
sox & Audiowerkzeuge
Das Skript nutzt sox an zwei Stellen: zur Audiovorverarbeitung
(Bandpass-Filter für Telefonfrequenzen) und zur MP3→WAV-Konvertierung für Asterisk.
# sox mit MP3-Unterstützung (bereits in Schritt 2, zur Sicherheit nochmal)
apt install -y sox libsox-fmt-mp3 libsox-fmt-all
# ffmpeg (Whisper intern benötigt)
apt install -y ffmpeg
# sox-Installation testen
sox --version
# Kurztest: Stummes WAV erzeugen und konvertieren
sox -n /tmp/test.wav trim 0.0 1.0
sox /tmp/test.wav -r 16000 -c 1 /tmp/test16k.wav \
highpass 300 lowpass 3200 norm -6
echo "sox OK"
norm -6 normalisiert die Lautstärke auf –6 dBFS.
Konfigurationsdatei vermittlung.json
Das Skript liest die Namensliste aus
/etc/asterisk/vermittlung.json.
Die Datei enthält ein JSON-Objekt mit dem Schlüssel "nebenstellen",
in dem Namen (Kleinbuchstaben) auf Nummern gemappt werden.
{
"nebenstellen": {
"roland": "1004",
"silvia": "1006",
"volker": "1033",
"sebastian": "1040",
"michael": "1050",
"zeitansage": "222",
"wetter": "333"
}
}
# Datei anlegen und Berechtigungen setzen
nano /etc/asterisk/vermittlung.json
# Asterisk-User braucht Lesezugriff
chown root:asterisk /etc/asterisk/vermittlung.json
chmod 640 /etc/asterisk/vermittlung.json
# JSON-Syntax prüfen
python3 -c "import json; json.load(open('/etc/asterisk/vermittlung.json')); print('JSON OK')"
"volker junghard" werden ebenfalls unterstützt.
Skript einrichten
Das AGI-Skript kommt in das Asterisk-AGI-Verzeichnis:
# Skript ins AGI-Verzeichnis kopieren
cp whisper_vermittlung.py /usr/share/asterisk/agi-bin/
chmod 755 /usr/share/asterisk/agi-bin/whisper_vermittlung.py
chown asterisk:asterisk /usr/share/asterisk/agi-bin/whisper_vermittlung.py
# Shebang prüfen – muss auf python3 zeigen
head -1 /usr/share/asterisk/agi-bin/whisper_vermittlung.py
# Erwartet: #!/usr/bin/env python3
# Python3-Pfad ermitteln (für Debugging)
which python3
Asterisk Dialplan (extensions.conf – Beispiel)
; Aufnahme starten, dann Whisper AGI aufrufen
exten => s,1,Answer()
same => n,Record(/tmp/whisper_input.wav,3,10,k)
same => n,AGI(whisper_vermittlung.py,/tmp/whisper_input)
same => n,GotoIf($[${RECOGNIZED} = error]?fehler,1)
same => n,GotoIf($[${RECOGNIZED} = nichts]?nochmal,1)
same => n,Dial(SIP/${RECOGNIZED})
exten => fehler,1,Playback(sorry)
exten => nochmal,1,Playback(bitte-nochmals)
.wav automatisch an, falls die Datei nicht direkt gefunden wird.
Installation testen
Whisper-Erkennung ohne Asterisk direkt auf der Kommandozeile testen:
# 1. Testaufnahme erzeugen (Text-to-Speech → WAV)
python3 -c "
from gtts import gTTS
tts = gTTS('Bitte verbinden Sie mich mit Roland', lang='de')
tts.save('/tmp/test_input.mp3')
"
sox /tmp/test_input.mp3 -r 8000 -c 1 -e signed-integer -b 16 /tmp/test_input.wav
# 2. Whisper direkt testen
python3 -c "
import whisper
model = whisper.load_model('/opt/whisper-models/base.pt')
r = model.transcribe('/tmp/test_input.wav', language='de', fp16=False)
print('Erkannt:', r['text'])
"
# 3. Vollständiges AGI-Skript mit simuliertem AGI-Kontext testen
# (leere Headerzeile am Anfang simuliert AGI-Protokoll)
echo "" | python3 /usr/share/asterisk/agi-bin/whisper_vermittlung.py /tmp/test_input
VERBOSE "Name erkannt: roland -> 1004" 1
und SET VARIABLE RECOGNIZED 1004 aus. Das ist korrekt.
Troubleshooting
ModuleNotFoundError: No module named 'whisper'
# Prüfen, welches Python Asterisk verwendet
which python3
python3 -c "import sys; print(sys.path)"
# Whisper ggf. für den exakten Python-Pfad nochmals installieren
/usr/bin/python3 -m pip install openai-whisper --break-system-packages
sox: no handler for file extension 'mp3'
apt install -y libsox-fmt-mp3 libsox-fmt-all
sox --version # muss mp3 in der Liste zeigen
Datei nicht gefunden (WAV-Pfad)
/tmp/ für den Asterisk-User beschreibbar ist:
ls -la /tmp/ – muss rwxrwxrwt zeigen.
Whisper sehr langsam
Auf älterer Hardware (ohne GPU) dauert die Transkription mit dem
base-Modell 3–10 Sekunden. Das tiny-Modell
ist deutlich schneller bei etwas geringerer Genauigkeit.
MODELL_PFAD im Skript entsprechend anpassen und
tiny.pt herunterladen.
gTTS schlägt fehl (kein Internet)
gTTS benötigt eine Internetverbindung (Google-Server). Für Offline-Betrieb
kann pyttsx3 als lokale Alternative eingesetzt werden –
dann müssen die Aufrufe in ansage_sprechen() angepasst werden.
# Offline-Alternative installieren
apt install -y espeak espeak-ng
pip3 install pyttsx3 --break-system-packages
Alle Abhängigkeiten auf einen Blick
python3 -c "
checks = {
'whisper': 'openai-whisper',
'gtts': 'gTTS',
'torch': 'PyTorch',
'subprocess': 'stdlib',
'json': 'stdlib',
}
for mod, label in checks.items():
try:
__import__(mod)
print(f' ✓ {label}')
except ImportError:
print(f' ✗ {label} <-- FEHLT, bitte installieren')
"
which sox ffmpeg && echo " ✓ sox + ffmpeg vorhanden"
test -f /opt/whisper-models/base.pt && echo " ✓ Modell vorhanden" || echo " ✗ Modell FEHLT"
test -f /etc/asterisk/vermittlung.json && echo " ✓ vermittlung.json vorhanden" || echo " ✗ vermittlung.json FEHLT"