|
| 1 | +# DTMF Sender |
| 2 | + |
| 3 | +This guide explains how to use the DTMF (Dual-Tone Multi-Frequency) sender functionality with the webrtc-java library. DTMF senders allow you to send DTMF tones over WebRTC audio connections, which is useful for interactive voice response (IVR) systems and telephony applications. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +WebRTC DTMF senders allow you to: |
| 8 | +- Send DTMF tones over an established audio connection |
| 9 | +- Configure tone duration and inter-tone gap |
| 10 | +- Monitor tone transmission events |
| 11 | +- Check if DTMF tones can be inserted |
| 12 | + |
| 13 | +DTMF tones are the audible tones generated when pressing keys on a telephone keypad. The supported DTMF tones are: 0-9, A-D, *, and #. In addition, the special character ',' (comma) can be used to insert a 2-second delay between tones. |
| 14 | + |
| 15 | +## Getting a DTMF Sender |
| 16 | + |
| 17 | +To use DTMF functionality, you need an established `RTCPeerConnection` with an audio track. You can then get the DTMF sender from the RTP sender associated with the audio track: |
| 18 | + |
| 19 | +```java |
| 20 | +import dev.onvoid.webrtc.RTCPeerConnection; |
| 21 | +import dev.onvoid.webrtc.RTCRtpSender; |
| 22 | +import dev.onvoid.webrtc.RTCDtmfSender; |
| 23 | +import dev.onvoid.webrtc.media.audio.AudioTrack; |
| 24 | + |
| 25 | +// Assuming you already have a PeerConnectionFactory and RTCConfiguration |
| 26 | +RTCPeerConnection peerConnection = factory.createPeerConnection(config, peerConnectionObserver); |
| 27 | + |
| 28 | +// Create and add an audio track |
| 29 | +AudioTrackSource audioSource = factory.createAudioSource(new AudioOptions()); |
| 30 | +AudioTrack audioTrack = factory.createAudioTrack("audioTrack", audioSource); |
| 31 | + |
| 32 | +// Add the track to the peer connection |
| 33 | +List<String> streamIds = new ArrayList<>(); |
| 34 | +streamIds.add("stream1"); |
| 35 | +RTCRtpSender sender = peerConnection.addTrack(audioTrack, streamIds); |
| 36 | + |
| 37 | +// Get the DTMF sender |
| 38 | +RTCDtmfSender dtmfSender = sender.getDtmfSender(); |
| 39 | +``` |
| 40 | + |
| 41 | +## Checking DTMF Capability |
| 42 | + |
| 43 | +Before attempting to send DTMF tones, you should check if the DTMF sender is capable of sending tones: |
| 44 | + |
| 45 | +```java |
| 46 | +if (dtmfSender != null && dtmfSender.canInsertDtmf()) { |
| 47 | + // DTMF is supported and can be used |
| 48 | + System.out.println("DTMF is supported"); |
| 49 | +} else { |
| 50 | + // DTMF is not supported |
| 51 | + System.out.println("DTMF is not supported"); |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +The `canInsertDtmf()` method returns true if and only if: |
| 56 | +- The associated RTCRtpSender's track is non-null and is of kind "audio" |
| 57 | +- The RTCDtmfSender is able to send packets |
| 58 | +- A "telephone-event" codec has been negotiated |
| 59 | + |
| 60 | +## Sending DTMF Tones |
| 61 | + |
| 62 | +To send DTMF tones, use the `insertDtmf` method: |
| 63 | + |
| 64 | +```java |
| 65 | +// Send DTMF tones with custom duration (100ms) and inter-tone gap (70ms) |
| 66 | +boolean success = dtmfSender.insertDtmf("123", 100, 70); |
| 67 | +``` |
| 68 | + |
| 69 | +The `insertDtmf` method takes the following parameters: |
| 70 | +- `tones`: A string containing the DTMF tones to send |
| 71 | +- `duration`: The duration in milliseconds for each tone (default: 100ms) |
| 72 | +- `interToneGap`: The gap between tones in milliseconds (default: 50ms) |
| 73 | + |
| 74 | +The method returns `true` if the tones were successfully queued for transmission, or `false` if the operation failed. |
| 75 | + |
| 76 | +### Valid Tones |
| 77 | + |
| 78 | +The following characters are valid in the `tones` parameter: |
| 79 | +- Digits: 0-9 |
| 80 | +- Letters: A-D (or a-d, case-insensitive) |
| 81 | +- Symbols: * (asterisk), # (pound/hash) |
| 82 | +- Special: , (comma) - inserts a 2-second delay |
| 83 | + |
| 84 | +Unrecognized characters are ignored. |
| 85 | + |
| 86 | +### Duration and Inter-Tone Gap Constraints |
| 87 | + |
| 88 | +The duration and inter-tone gap parameters have the following constraints: |
| 89 | +- Duration must be between 70ms and 6000ms (default: 100ms) |
| 90 | +- Inter-tone gap must be at least 50ms (default: 50ms) |
| 91 | + |
| 92 | +If these constraints are not met, the `insertDtmf` method will return `false`. |
| 93 | + |
| 94 | +## Monitoring DTMF Events |
| 95 | + |
| 96 | +To receive notifications about DTMF tone events, implement the `RTCDtmfSenderObserver` interface and register it with the DTMF sender: |
| 97 | + |
| 98 | +```java |
| 99 | +import dev.onvoid.webrtc.RTCDtmfSenderObserver; |
| 100 | + |
| 101 | +dtmfSender.registerObserver(new RTCDtmfSenderObserver() { |
| 102 | + @Override |
| 103 | + public void onToneChange(String tone, String toneBuffer) { |
| 104 | + if (tone == null || tone.isEmpty()) { |
| 105 | + System.out.println("All tones have been played"); |
| 106 | + } else { |
| 107 | + System.out.println("Playing tone: " + tone); |
| 108 | + System.out.println("Remaining tones: " + toneBuffer); |
| 109 | + } |
| 110 | + } |
| 111 | +}); |
| 112 | +``` |
| 113 | + |
| 114 | +The `onToneChange` method is called: |
| 115 | +- When a new tone starts playing, with the tone character and the remaining tones buffer |
| 116 | +- When all tones have finished playing, with an empty string for both parameters |
| 117 | + |
| 118 | +## Getting DTMF Properties |
| 119 | + |
| 120 | +You can query various properties of the DTMF sender: |
| 121 | + |
| 122 | +```java |
| 123 | +// Get the tones currently in the queue |
| 124 | +String remainingTones = dtmfSender.tones(); |
| 125 | + |
| 126 | +// Get the current duration setting |
| 127 | +int duration = dtmfSender.duration(); |
| 128 | + |
| 129 | +// Get the current inter-tone gap setting |
| 130 | +int interToneGap = dtmfSender.interToneGap(); |
| 131 | +``` |
| 132 | + |
| 133 | +## Cleanup |
| 134 | + |
| 135 | +When you're done with the DTMF sender, you should unregister any observers: |
| 136 | + |
| 137 | +```java |
| 138 | +// Unregister the observer |
| 139 | +dtmfSender.unregisterObserver(); |
| 140 | +``` |
| 141 | + |
| 142 | +Note that you don't need to explicitly dispose of the DTMF sender, as it will be cleaned up when the associated RTP sender is disposed. |
| 143 | + |
| 144 | +## Best Practices |
| 145 | + |
| 146 | +1. **Check Capability**: Always check if DTMF is supported using `canInsertDtmf()` before attempting to send tones. |
| 147 | + |
| 148 | +2. **Error Handling**: Check the return value of `insertDtmf()` to ensure the tones were successfully queued. |
| 149 | + |
| 150 | +3. **Observer Cleanup**: Always unregister observers when you're done to prevent memory leaks. |
| 151 | + |
| 152 | +4. **Tone Duration**: Use appropriate tone durations based on your application needs: |
| 153 | + - For standard telephony applications, the default 100ms is usually sufficient |
| 154 | + - For IVR systems that might need more processing time, consider longer durations |
| 155 | + |
| 156 | +5. **Tone Buffering**: Be aware that tones are queued and played sequentially. If you need to cancel queued tones, you can call `insertDtmf("")` to clear the queue. |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +## Conclusion |
| 161 | + |
| 162 | +The RTCDtmfSender provides a standard way to send DTMF tones over WebRTC audio connections. This functionality is particularly useful for applications that need to interact with traditional telephony systems, IVR systems, or any service that uses DTMF for signaling. |
| 163 | + |
| 164 | +By following the guidelines in this document, you can effectively integrate DTMF functionality into your WebRTC applications, enabling users to interact with automated systems or trigger actions using their device's keypad. |
| 165 | + |
| 166 | +For more information on other WebRTC features, refer to the additional guides in the documentation. |
0 commit comments