Start · Sprachen · JavaScript · Referenz · RTCDTMFSender: tonechange

RTCDTMFSender: tonechange

Ereignis

Wird an einem <code>RTCDTMFSender</code> ausgelöst, wenn ein DTMF-Ton zu spielen beginnt oder die Tonfolge vollständig abgespielt ist.

seit JavaScript Baseline: alle modernen Browser (Chrome, Edge, Fir Kategorie: webapi

Signatur

dtmfSender.addEventListener("tonechange", handler)

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

Typ
void
Beschreibung
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);
}
Spiele Ton: 1 Spiele Ton: 2 Spiele Ton: # Alle Töne gesendet.

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');
Menüauswahl abgeschlossen

// Wichtig · Fallstricke

  • Ende der Folge: Das letzte tonechange hat tone === \"\". Prüfe mit === '' und nicht auf „falsy“, sonst verwechselst du es leicht mit anderen Werten.
  • Pausen: Ein Komma (,) löst ebenfalls ein tonechange aus, ist aber kein hörbarer Ton, sondern eine Pause von 2 Sekunden.
  • Warteschlange wird ersetzt: Ein erneuter Aufruf von insertDTMF() ersetzt die restliche Warteschlange. Mit insertDTMF('') wird sie geleert. Ob danach noch ein abschließendes Ereignis mit leerem tone kommt, kann je nach Browser unterschiedlich sein.
  • Verfügbarkeit: RTCRtpSender.dtmf gibt es nur bei Audio-Sendern. Bei Video-Sendern ist es null. Vor dem Senden canInsertDTMF prüfen: Es ist z. B. false, solange die Verbindung nicht aufgebaut ist oder die Gegenstelle kein telephone-event ausgehandelt hat.
  • Kompatibilität: Wird in Chrome, Edge, Firefox und Safari unterstützt. Das veraltete RTCPeerConnection.createDTMFSender() solltest du nicht mehr verwenden, sondern stattdessen sender.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.