Signatur
Beschreibung
Das Ereignis tonechange gehört zur WebRTC-API. Es wird an einem RTCDTMFSender ausgelöst, sobald ein Ton aus der Warteschlange zu spielen beginnt, die zuvor mit insertDTMF() befüllt wurde. Wenn die ganze Tonfolge abgespielt ist, wird es ein letztes Mal ausgelöst, dann mit einem leeren String als tone.
Der Handler bekommt ein RTCDTMFToneChangeEvent. Dessen Eigenschaft tone enthält das aktuelle Zeichen (0–9, *, #, A–D oder , für eine Pause von 2 Sekunden). Ist tone ein leerer String (""), ist die Wiedergabe beendet.
Typische Einsatzfälle sind WebRTC-Telefonie und Gateways zum Telefonnetz (SIP/PSTN), etwa zur Bedienung von Sprachmenüs („Drücken Sie 1 …“). Mit dem Ereignis kann man Wähltasten in der Oberfläche hervorheben, den Fortschritt anzeigen oder erst nach Ende der Tonfolge weitere Aktionen starten.
Einen Handler registriert man mit addEventListener("tonechange", handler) oder über die Eigenschaft ontonechange. Das Ereignis steigt nicht auf (bubbles: false) und lässt sich nicht abbrechen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "tonechange". |
|
| $handler Pflicht | (event: RTCDTMFToneChangeEvent) => void | Callback, der ein RTCDTMFToneChangeEvent bekommt. event.tone ist das gerade gespielte Zeichen bzw. "" am Ende der Folge. |
|
| $options | boolean|AddEventListenerOptions | false | Übliche Optionen von addEventListener, z. B. { once: true } oder { signal }. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein RTCDTMFToneChangeEvent mit der Eigenschaft tone (string).Beispiele
Gespielte Töne mit addEventListener protokollieren
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const [track] = stream.getAudioTracks();
const sender = pc.addTrack(track, stream);
// ... Verbindung per Signalisierung aufbauen ...
const dtmf = sender.dtmf;
dtmf.addEventListener('tonechange', (event) => {
if (event.tone !== '') {
console.log(`Spiele Ton: ${event.tone}`);
} else {
console.log('Alle Töne gesendet.');
}
});
if (dtmf?.canInsertDTMF) {
dtmf.insertDTMF('12#', 100, 70);
}
Handler über die ontonechange-Eigenschaft setzen und wieder entfernen
const dtmf = sender.dtmf;
dtmf.ontonechange = ({ tone }) => {
document.querySelector('#status').textContent =
tone ? `Wähle ${tone} …` : 'Fertig';
};
dtmf.insertDTMF('0800,123');
// Später Handler entfernen:
// dtmf.ontonechange = null;
Wähltaste in der Oberfläche hervorheben und Listener sauber entfernen
const highlightKey = ({ tone }) => {
document.querySelectorAll('.key').forEach((el) => el.classList.remove('active'));
if (tone && tone !== ',') {
document.querySelector(`.key[data-tone="${CSS.escape(tone)}"]`)?.classList.add('active');
}
if (tone === '') {
// Folge beendet → Listener entfernen
sender.dtmf.removeEventListener('tonechange', highlightKey);
}
};
sender.dtmf.addEventListener('tonechange', highlightKey);
sender.dtmf.insertDTMF('*42#');
Auf das Ende einer Tonfolge per Promise warten
const sendDTMF = (dtmf, tones, duration = 100, gap = 70) =>
new Promise((resolve, reject) => {
if (!dtmf?.canInsertDTMF) {
reject(new Error('DTMF wird gerade nicht unterstützt'));
return;
}
const onChange = ({ tone }) => {
if (tone === '') {
dtmf.removeEventListener('tonechange', onChange);
resolve();
}
};
dtmf.addEventListener('tonechange', onChange);
dtmf.insertDTMF(tones, duration, gap);
});
await sendDTMF(sender.dtmf, '1');
await sendDTMF(sender.dtmf, '4711#');
console.log('Menüauswahl abgeschlossen');
// Wichtig · Fallstricke
- Ende der Folge: Das letzte
tonechangehattone === \"\". Prüfe mit=== ''und nicht auf „falsy“, sonst verwechselst du es leicht mit anderen Werten. - Pausen: Ein Komma (
,) löst ebenfalls eintonechangeaus, ist aber kein hörbarer Ton, sondern eine Pause von 2 Sekunden. - Warteschlange wird ersetzt: Ein erneuter Aufruf von
insertDTMF()ersetzt die restliche Warteschlange. MitinsertDTMF('')wird sie geleert. Ob danach noch ein abschließendes Ereignis mit leeremtonekommt, kann je nach Browser unterschiedlich sein. - Verfügbarkeit:
RTCRtpSender.dtmfgibt es nur bei Audio-Sendern. Bei Video-Sendern ist esnull. Vor dem SendencanInsertDTMFprüfen: Es ist z. B.false, solange die Verbindung nicht aufgebaut ist oder die Gegenstelle keintelephone-eventausgehandelt hat. - Kompatibilität: Wird in Chrome, Edge, Firefox und Safari unterstützt. Das veraltete
RTCPeerConnection.createDTMFSender()solltest du nicht mehr verwenden, sondern stattdessensender.dtmf. - DTMF wird als RTP-Ereignis nach RFC 4733 übertragen, nicht als hörbares Audiosignal. Ob die Gegenstelle es verarbeitet, hängt von deren Unterstützung ab.