Signatur
Beschreibung
insertDTMF() sendet DTMF-Töne (Dual-Tone Multi-Frequency, also die Tastentöne eines Telefons) über eine bestehende WebRTC-Audioverbindung. Das braucht man vor allem, wenn ein Browser-Softphone mit klassischen Telefonanlagen oder Sprachmenüs (IVR) spricht, etwa „Drücken Sie die 1 für den Vertrieb“, oder wenn Durchwahlen und PIN-Codes über ein SIP-/WebRTC-Gateway eingegeben werden.
Das RTCDTMFSender-Objekt bekommt man über die Eigenschaft dtmf eines RTCRtpSender, der einen Audio-Track sendet. Die Töne werden nicht als hörbares Audio gemischt, sondern als RTP-Telephone-Events nach RFC 4733 übertragen. Deshalb muss die Gegenstelle den Codec telephone-event ausgehandelt haben.
Ein Aufruf ersetzt den aktuellen Tonpuffer (toneBuffer). Töne, die noch nicht gespielt wurden, werden also verworfen. Soll etwas angehängt werden, übergibt man sender.toneBuffer + neueTöne. Für jeden gestarteten Ton wird das Ereignis tonechange ausgelöst. Wenn der Puffer leer ist, folgt noch ein tonechange mit leerem tone.
Gültige Zeichen sind 0–9, A–D (Groß- und Kleinschreibung egal), #, * und das Komma ,. Das Komma fügt eine Pause von 2 Sekunden ein, zum Beispiel um auf eine Ansage zu warten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $tones Pflicht | string | Folge der zu sendenden Töne: 0–9, A–D, #, * sowie , für 2 Sekunden Pause. Ein leerer String leert den Tonpuffer und bricht damit laufende Sequenzen ab. |
|
| $duration | number | 100 | Dauer jedes Tons in Millisekunden. Werte unter 40 werden auf 40 angehoben, Werte über 6000 auf 6000 begrenzt. |
| $interToneGap | number | 70 | Pause zwischen zwei Tönen in Millisekunden. Das Minimum ist 30 ms, kleinere Werte werden angehoben. |
Rückgabewert
undefined). Den Fortschritt verfolgt man über das Ereignis tonechange und die Eigenschaft toneBuffer.Beispiele
PIN an ein Sprachmenü (IVR) senden
// pc ist eine bereits verbundene RTCPeerConnection mit Mikrofon-Track
const audioSender = pc.getSenders().find((s) => s.track?.kind === 'audio');
const dtmf = audioSender?.dtmf;
if (dtmf?.canInsertDTMF) {
// Zuerst "1" wählen, 2 s auf die Ansage warten, dann PIN + Raute
dtmf.insertDTMF('1,4711#', 120, 80);
console.log('Warteschlange:', dtmf.toneBuffer);
} else {
console.warn('DTMF wird von dieser Verbindung nicht unterstützt.');
}
Fortschritt mit tonechange verfolgen
const dtmf = pc.getSenders().find((s) => s.track?.kind === 'audio').dtmf;
dtmf.addEventListener('tonechange', (event) => {
if (event.tone === '') {
console.log('Alle Töne gesendet.');
} else {
console.log(`Sende Ton: ${event.tone}`);
}
});
dtmf.insertDTMF('123');
Wähltastatur: Töne anhängen statt ersetzen
const dtmf = pc.getSenders().find((s) => s.track?.kind === 'audio').dtmf;
document.querySelectorAll('button[data-key]').forEach((button) => {
button.addEventListener('click', () => {
const key = button.dataset.key; // z. B. "5", "*" oder "#"
try {
// Noch nicht gespielte Töne behalten und die neue Taste anhängen
dtmf.insertDTMF(dtmf.toneBuffer + key);
} catch (err) {
console.error(`${err.name}: ${err.message}`);
}
});
});
// Laufende Sequenz abbrechen
document.querySelector('#abbrechen').addEventListener('click', () => {
dtmf.insertDTMF('');
});
// Wichtig · Fallstricke
- Puffer wird ersetzt: Jeder Aufruf überschreibt den
toneBuffer. Wer schnell hintereinander Tasten sendet, ohne den Puffer anzuhängen, verliert Töne. - Nur bei Audio: Bei Video-Sendern ist
RTCRtpSender.dtmfnull. Vor dem Aufruf sollte mancanInsertDTMFprüfen. Der Wert istfalse, wenn die Gegenstelletelephone-eventnicht ausgehandelt hat. - Ausnahmen:
InvalidStateErrortritt auf, wenn der zugehörigeRTCRtpTransceivergestoppt ist oder seine Richtung wedersendrecvnochsendonlyist.InvalidCharacterErrortritt bei unzulässigen Zeichen intonesauf, etwa Leerzeichen oder Bindestrichen. Nutzereingaben sollte man deshalb vorher filtern, z. B. mit/[^0-9A-D#*,]/gi. - Werte werden begrenzt:
durationundinterToneGapwerden ohne Fehlermeldung auf den erlaubten Bereich gesetzt (40–6000 ms bzw. mindestens 30 ms). - Kompatibilität: Wird in allen aktuellen Browsern unterstützt. Das veraltete
RTCPeerConnection.createDTMFSender()sollte man nicht mehr verwenden, sondernRTCRtpSender.dtmf. - Hörbar ist DTMF nur, wenn die Gegenstelle (z. B. ein SIP-Gateway) die RFC-4733-Ereignisse auswertet oder in Töne umwandelt. Lokal hört man nichts.