Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ The library provides a comprehensive set of Java classes that map to the WebRTC

For more detailed information, check out the documentation:

- **[Quickstart](https://jrtc.dev/#/quickstart)** - Get up and running quickly with webrtc-java
- **[Guides](https://jrtc.dev/#/guide/overview)** - Comprehensive documentation on using the library
- **[Examples](https://jrtc.dev/#/examples)** - Sample code demonstrating various features
- **[Build Notes](https://jrtc.dev/#/build)** - Instructions for building the library from source
- [Quickstart](https://jrtc.dev/#/quickstart) - Get up and running quickly with webrtc-java
- [Guides](https://jrtc.dev/#/guide/overview) - Comprehensive documentation on using the library
- [Examples](https://jrtc.dev/#/examples) - Sample code demonstrating various features
- [Build Notes](https://jrtc.dev/#/build) - Instructions for building the library from source

## License

Expand Down
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [Bitrate and Framerate Constraints](guide/constraints.md)
- [Desktop Capture](guide/desktop_capture.md)
- [Data Channels](guide/data_channels.md)
- [DTMF Sender](guide/dtmf_sender.md)
- [RTC Stats](guide/rtc_stats.md)
- [Logging](guide/logging.md)

Expand Down
166 changes: 166 additions & 0 deletions docs/guide/dtmf_sender.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# DTMF Sender

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.

## Overview

WebRTC DTMF senders allow you to:
- Send DTMF tones over an established audio connection
- Configure tone duration and inter-tone gap
- Monitor tone transmission events
- Check if DTMF tones can be inserted

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.

## Getting a DTMF Sender

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:

```java
import dev.onvoid.webrtc.RTCPeerConnection;
import dev.onvoid.webrtc.RTCRtpSender;
import dev.onvoid.webrtc.RTCDtmfSender;
import dev.onvoid.webrtc.media.audio.AudioTrack;

// Assuming you already have a PeerConnectionFactory and RTCConfiguration
RTCPeerConnection peerConnection = factory.createPeerConnection(config, peerConnectionObserver);

// Create and add an audio track
AudioTrackSource audioSource = factory.createAudioSource(new AudioOptions());
AudioTrack audioTrack = factory.createAudioTrack("audioTrack", audioSource);

// Add the track to the peer connection
List<String> streamIds = new ArrayList<>();
streamIds.add("stream1");
RTCRtpSender sender = peerConnection.addTrack(audioTrack, streamIds);

// Get the DTMF sender
RTCDtmfSender dtmfSender = sender.getDtmfSender();
```

## Checking DTMF Capability

Before attempting to send DTMF tones, you should check if the DTMF sender is capable of sending tones:

```java
if (dtmfSender != null && dtmfSender.canInsertDtmf()) {
// DTMF is supported and can be used
System.out.println("DTMF is supported");
} else {
// DTMF is not supported
System.out.println("DTMF is not supported");
}
```

The `canInsertDtmf()` method returns true if and only if:
- The associated RTCRtpSender's track is non-null and is of kind "audio"
- The RTCDtmfSender is able to send packets
- A "telephone-event" codec has been negotiated

## Sending DTMF Tones

To send DTMF tones, use the `insertDtmf` method:

```java
// Send DTMF tones with custom duration (100ms) and inter-tone gap (70ms)
boolean success = dtmfSender.insertDtmf("123", 100, 70);
```

The `insertDtmf` method takes the following parameters:
- `tones`: A string containing the DTMF tones to send
- `duration`: The duration in milliseconds for each tone (default: 100ms)
- `interToneGap`: The gap between tones in milliseconds (default: 50ms)

The method returns `true` if the tones were successfully queued for transmission, or `false` if the operation failed.

### Valid Tones

The following characters are valid in the `tones` parameter:
- Digits: 0-9
- Letters: A-D (or a-d, case-insensitive)
- Symbols: * (asterisk), # (pound/hash)
- Special: , (comma) - inserts a 2-second delay

Unrecognized characters are ignored.

### Duration and Inter-Tone Gap Constraints

The duration and inter-tone gap parameters have the following constraints:
- Duration must be between 70ms and 6000ms (default: 100ms)
- Inter-tone gap must be at least 50ms (default: 50ms)

If these constraints are not met, the `insertDtmf` method will return `false`.

## Monitoring DTMF Events

To receive notifications about DTMF tone events, implement the `RTCDtmfSenderObserver` interface and register it with the DTMF sender:

```java
import dev.onvoid.webrtc.RTCDtmfSenderObserver;

dtmfSender.registerObserver(new RTCDtmfSenderObserver() {
@Override
public void onToneChange(String tone, String toneBuffer) {
if (tone == null || tone.isEmpty()) {
System.out.println("All tones have been played");
} else {
System.out.println("Playing tone: " + tone);
System.out.println("Remaining tones: " + toneBuffer);
}
}
});
```

The `onToneChange` method is called:
- When a new tone starts playing, with the tone character and the remaining tones buffer
- When all tones have finished playing, with an empty string for both parameters

## Getting DTMF Properties

You can query various properties of the DTMF sender:

```java
// Get the tones currently in the queue
String remainingTones = dtmfSender.tones();

// Get the current duration setting
int duration = dtmfSender.duration();

// Get the current inter-tone gap setting
int interToneGap = dtmfSender.interToneGap();
```

## Cleanup

When you're done with the DTMF sender, you should unregister any observers:

```java
// Unregister the observer
dtmfSender.unregisterObserver();
```

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.

## Best Practices

1. **Check Capability**: Always check if DTMF is supported using `canInsertDtmf()` before attempting to send tones.

2. **Error Handling**: Check the return value of `insertDtmf()` to ensure the tones were successfully queued.

3. **Observer Cleanup**: Always unregister observers when you're done to prevent memory leaks.

4. **Tone Duration**: Use appropriate tone durations based on your application needs:
- For standard telephony applications, the default 100ms is usually sufficient
- For IVR systems that might need more processing time, consider longer durations

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.

---

## Conclusion

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.

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.

For more information on other WebRTC features, refer to the additional guides in the documentation.
1 change: 1 addition & 0 deletions docs/guide/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This section provides detailed guides for various features of the webrtc-java li
- [Audio Processing](guide/audio_processing.md) - Voice processing components
- [Bitrate and Framerate Constraints](guide/constraints.md) - Controlling media quality
- [Desktop Capture](guide/desktop_capture.md) - Capturing and sharing screens and windows
- [DTMF Sender](guide/dtmf_sender.md) - Sending DTMF tones in a call

## Data Communication

Expand Down
69 changes: 69 additions & 0 deletions webrtc-jni/src/main/cpp/include/JNI_RTCDtmfSender.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions webrtc-jni/src/main/cpp/include/JNI_RTCRtpSender.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions webrtc-jni/src/main/cpp/include/api/RTCDtmfSender.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2019 Alex Andres
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef JNI_WEBRTC_API_RTC_DTMF_SENDER_H_
#define JNI_WEBRTC_API_RTC_DTMF_SENDER_H_

#include "JavaClass.h"
#include "JavaRef.h"

#include "api/dtmf_sender_interface.h"

#include <jni.h>

namespace jni
{
namespace RTCDtmfSender
{
class JavaRTCDtmfSenderClass : public JavaClass
{
public:
explicit JavaRTCDtmfSenderClass(JNIEnv * env);

jclass cls;
jmethodID ctor;
};

JavaLocalRef<jobject> toJava(JNIEnv * env);
};
}

#endif
55 changes: 55 additions & 0 deletions webrtc-jni/src/main/cpp/include/api/RTCDtmfSenderObserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2019 Alex Andres
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef JNI_WEBRTC_API_RTC_DTMF_SENDER_OBSERVER_H_
#define JNI_WEBRTC_API_RTC_DTMF_SENDER_OBSERVER_H_

#include "JavaClass.h"
#include "JavaRef.h"

#include "api/dtmf_sender_interface.h"

#include <jni.h>
#include <memory>

namespace jni
{
class RTCDtmfSenderObserver : public webrtc::DtmfSenderObserverInterface
{
public:
explicit RTCDtmfSenderObserver(JNIEnv * env, const JavaGlobalRef<jobject> & observer);
~RTCDtmfSenderObserver() = default;

// DtmfSenderObserverInterface implementation.
void OnToneChange(const std::string & tone, const std::string & tone_buffer) override;

private:
class JavaRTCDtmfSenderObserverClass : public JavaClass
{
public:
explicit JavaRTCDtmfSenderObserverClass(JNIEnv * env);

jmethodID onToneChange;
};

private:
JavaGlobalRef<jobject> observer;

const std::shared_ptr<JavaRTCDtmfSenderObserverClass> javaClass;
};
}

#endif
Loading