Skip to content

Commit 2e81ad0

Browse files
feat: add noise cancellation apis (#12)
* siwth to stream fork and add audio files * 125.2.0-alpha.1 * add to options * 125.3.0-alpha.1 * ios: Add audioProcessingModule to WebRTCModuleOptions (#13) * 125.3.0-alpha.2 * wrong package name fix * 125.3.0-alpha.3 * fix missing package word * 125.3.0-alpha.4 * update peer dep of rn --------- Co-authored-by: davidliu <davidliu@deviange.net>
1 parent 6fd0178 commit 2e81ad0

10 files changed

Lines changed: 130 additions & 8 deletions

File tree

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ android {
3131
}
3232

3333
dependencies {
34-
api 'io.github.webrtc-sdk:android:125.6422.06.1'
34+
api 'io.getstream:stream-webrtc-android:1.3.8'
3535
implementation 'com.facebook.react:react-native:+'
3636
implementation "androidx.core:core:1.7.0"
3737
}

android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import com.facebook.react.bridge.WritableMap;
2222
import com.facebook.react.module.annotations.ReactModule;
2323
import com.facebook.react.modules.core.DeviceEventManagerModule;
24+
import com.oney.WebRTCModule.audio.AudioProcessingFactoryProvider;
25+
import com.oney.WebRTCModule.audio.AudioProcessingController;
2426
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoDecoderFactory;
2527
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
2628

@@ -64,6 +66,8 @@ public WebRTCModule(ReactApplicationContext reactContext) {
6466
VideoDecoderFactory decoderFactory = options.videoDecoderFactory;
6567
Loggable injectableLogger = options.injectableLogger;
6668
Logging.Severity loggingSeverity = options.loggingSeverity;
69+
AudioProcessingFactoryProvider audioProcessingFactoryProvider = options.audioProcessingFactoryProvider;
70+
6771
String fieldTrials = options.fieldTrials;
6872

6973
PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions.builder(reactContext)
@@ -96,10 +100,15 @@ public WebRTCModule(ReactApplicationContext reactContext) {
96100
Log.d(TAG, "Using video encoder factory: " + encoderFactory.getClass().getCanonicalName());
97101
Log.d(TAG, "Using video decoder factory: " + decoderFactory.getClass().getCanonicalName());
98102

103+
if(audioProcessingFactoryProvider == null) {
104+
audioProcessingFactoryProvider = new AudioProcessingController();
105+
}
106+
99107
mFactory = PeerConnectionFactory.builder()
100108
.setAudioDeviceModule(adm)
101109
.setVideoEncoderFactory(encoderFactory)
102110
.setVideoDecoderFactory(decoderFactory)
111+
.setAudioProcessingFactory(audioProcessingFactoryProvider.getFactory())
103112
.createPeerConnectionFactory();
104113

105114
// PeerConnectionFactory now owns the adm native pointer, and we don't need it anymore.

android/src/main/java/com/oney/WebRTCModule/WebRTCModuleOptions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.oney.WebRTCModule;
22

3+
import com.oney.WebRTCModule.audio.AudioProcessingFactoryProvider;
4+
35
import org.webrtc.Loggable;
46
import org.webrtc.Logging;
57
import org.webrtc.VideoDecoderFactory;
@@ -16,6 +18,7 @@ public class WebRTCModuleOptions {
1618
public Logging.Severity loggingSeverity;
1719
public String fieldTrials;
1820
public boolean enableMediaProjectionService;
21+
public AudioProcessingFactoryProvider audioProcessingFactoryProvider;
1922

2023
public static WebRTCModuleOptions getInstance() {
2124
if (instance == null) {
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.oney.WebRTCModule.audio;
2+
3+
import org.webrtc.ExternalAudioProcessingFactory;
4+
5+
import java.nio.ByteBuffer;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
public class AudioProcessingAdapter implements ExternalAudioProcessingFactory.AudioProcessing {
10+
public interface ExternalAudioFrameProcessing {
11+
void initialize(int sampleRateHz, int numChannels);
12+
13+
void reset(int newRate);
14+
15+
void process(int numBands, int numFrames, ByteBuffer buffer);
16+
}
17+
18+
public AudioProcessingAdapter() {}
19+
List<ExternalAudioFrameProcessing> audioProcessors = new ArrayList<>();
20+
21+
public void addProcessor(ExternalAudioFrameProcessing audioProcessor) {
22+
synchronized (audioProcessors) {
23+
audioProcessors.add(audioProcessor);
24+
}
25+
}
26+
27+
public void removeProcessor(ExternalAudioFrameProcessing audioProcessor) {
28+
synchronized (audioProcessors) {
29+
audioProcessors.remove(audioProcessor);
30+
}
31+
}
32+
33+
@Override
34+
public void initialize(int sampleRateHz, int numChannels) {
35+
synchronized (audioProcessors) {
36+
for (ExternalAudioFrameProcessing audioProcessor : audioProcessors) {
37+
audioProcessor.initialize(sampleRateHz, numChannels);
38+
}
39+
}
40+
}
41+
42+
@Override
43+
public void reset(int newRate) {
44+
synchronized (audioProcessors) {
45+
for (ExternalAudioFrameProcessing audioProcessor : audioProcessors) {
46+
audioProcessor.reset(newRate);
47+
}
48+
}
49+
}
50+
51+
@Override
52+
public void process(int numBands, int numFrames, ByteBuffer buffer) {
53+
synchronized (audioProcessors) {
54+
for (ExternalAudioFrameProcessing audioProcessor : audioProcessors) {
55+
audioProcessor.process(numBands, numFrames, buffer);
56+
}
57+
}
58+
}
59+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.oney.WebRTCModule.audio;
2+
3+
import org.webrtc.AudioProcessingFactory;
4+
import org.webrtc.ExternalAudioProcessingFactory;
5+
6+
public class AudioProcessingController implements AudioProcessingFactoryProvider {
7+
/**
8+
* This is the audio processing module that will be applied to the audio stream after it is captured from the microphone.
9+
* This is useful for adding echo cancellation, noise suppression, etc.
10+
*/
11+
public final AudioProcessingAdapter capturePostProcessing = new AudioProcessingAdapter();
12+
/**
13+
* This is the audio processing module that will be applied to the audio stream before it is rendered to the speaker.
14+
*/
15+
public final AudioProcessingAdapter renderPreProcessing = new AudioProcessingAdapter();
16+
17+
public ExternalAudioProcessingFactory externalAudioProcessingFactory;
18+
19+
public AudioProcessingController() {
20+
this.externalAudioProcessingFactory = new ExternalAudioProcessingFactory();
21+
this.externalAudioProcessingFactory.setCapturePostProcessing(capturePostProcessing);
22+
this.externalAudioProcessingFactory.setRenderPreProcessing(renderPreProcessing);
23+
}
24+
25+
@Override
26+
public AudioProcessingFactory getFactory() {
27+
return this.externalAudioProcessingFactory;
28+
}
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.oney.WebRTCModule.audio;
2+
3+
import org.webrtc.AudioProcessingFactory;
4+
5+
// Define the common interface
6+
public interface AudioProcessingFactoryProvider {
7+
AudioProcessingFactory getFactory();
8+
}

ios/RCTWebRTC/WebRTCModule.m

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ - (instancetype)init {
4343
id<RTCAudioDevice> audioDevice = options.audioDevice;
4444
id<RTCVideoDecoderFactory> decoderFactory = options.videoDecoderFactory;
4545
id<RTCVideoEncoderFactory> encoderFactory = options.videoEncoderFactory;
46+
id<RTCAudioProcessingModule> audioProcessingModule = options.audioProcessingModule;
4647
NSDictionary *fieldTrials = options.fieldTrials;
4748
RTCLoggingSeverity loggingSeverity = options.loggingSeverity;
4849

@@ -69,9 +70,21 @@ - (instancetype)init {
6970
RCTLogInfo(@"Using video encoder factory: %@", NSStringFromClass([encoderFactory class]));
7071
RCTLogInfo(@"Using video decoder factory: %@", NSStringFromClass([decoderFactory class]));
7172

72-
_peerConnectionFactory = [[RTCPeerConnectionFactory alloc] initWithEncoderFactory:encoderFactory
73-
decoderFactory:decoderFactory
74-
audioDevice:audioDevice];
73+
if (audioProcessingModule != nil) {
74+
if (audioDevice != nil) {
75+
NSLog(@"Both audioProcessingModule and audioDevice are provided, but only one can be used. Ignoring audioDevice.");
76+
}
77+
RCTLogInfo(@"Using audio processing module: %@", NSStringFromClass([audioProcessingModule class]));
78+
_peerConnectionFactory = [[RTCPeerConnectionFactory alloc] initWithBypassVoiceProcessing:NO
79+
encoderFactory:encoderFactory
80+
decoderFactory:decoderFactory
81+
audioProcessingModule:audioProcessingModule];
82+
} else {
83+
RCTLogInfo(@"Using audio device: %@", NSStringFromClass([audioDevice class]));
84+
_peerConnectionFactory = [[RTCPeerConnectionFactory alloc] initWithEncoderFactory:encoderFactory
85+
decoderFactory:decoderFactory
86+
audioDevice:audioDevice];
87+
}
7588

7689
_peerConnections = [NSMutableDictionary new];
7790
_localStreams = [NSMutableDictionary new];

ios/RCTWebRTC/WebRTCModuleOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ NS_ASSUME_NONNULL_BEGIN
88
@property(nonatomic, strong, nullable) id<RTCVideoDecoderFactory> videoDecoderFactory;
99
@property(nonatomic, strong, nullable) id<RTCVideoEncoderFactory> videoEncoderFactory;
1010
@property(nonatomic, strong, nullable) id<RTCAudioDevice> audioDevice;
11+
@property(nonatomic, strong, nullable) id<RTCAudioProcessingModule> audioProcessingModule;
1112
@property(nonatomic, strong, nullable) NSDictionary *fieldTrials;
1213
@property(nonatomic, assign) RTCLoggingSeverity loggingSeverity;
1314
@property(nonatomic, assign) BOOL enableMultitaskingCameraAccess;

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stream-io/react-native-webrtc",
3-
"version": "125.2.1",
3+
"version": "125.3.0-alpha.4",
44
"repository": {
55
"type": "git",
66
"url": "git+https://github.com/GetStream/react-native-webrtc.git"
@@ -25,7 +25,7 @@
2525
"event-target-shim": "6.0.2"
2626
},
2727
"peerDependencies": {
28-
"react-native": ">=0.60.0"
28+
"react-native": ">=0.73.0"
2929
},
3030
"files": [
3131
"lib",

0 commit comments

Comments
 (0)