Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bengsfort committed Oct 30, 2023
0 parents commit a2eaa72
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 0 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Noice Patched WebRTC

This repo contains the patched [WebRTC](https://webrtc.org/) builds we require to fix some issues with [react-native-webrtc](https://github.com/react-native-webrtc/react-native-webrtc).

## Why?

The Chromium WebRTC library has some built-in assumptions that are not so great. For example, requesting microphone access and enabling the microphone automatically even when only being used for playback or requesting camera access by default.

Some of these issues can be fixed by in-place, such as the microphone issue by implementing your own Audio Device Manager (ADM), but that requires a huge level of effort as well as maintenance. In some cases, like this, it is best for us to apply battle-tested patches to the WebRTC source and cut manual builds.

## Builds

Builds are currently created manually, and then published manually. Ideally we can eventually automate it, but this is what it is now. Versioning follows the same versioning scheme as WebRTC/react-native webrtc:

```
<Chrome Major Version>.0.<Release Number>
```

Once published, update the platform podfile to point to the new released version:

```
s.dependency = { :http => 'https://github.com/noice-com/patched-webrtc/releases/download/<version-number>/WebRTC.xcframework.zip', :flatten => false }
```

## Creating a build

### iOS

1. Make sure you have Python installed and usable.
2. Follow the instructions in [react-native-webrtc/Building WebRTC](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/BuildingWebRTC.md) to get the WebRTC source on your machine and ready to build.
- Currently we are targeting revision M111, which would be WebRTC branch `5563`.
3. Apply the patches included in [patches/](./patches) using [`git apply <patch-file>`](https://git-scm.com/docs/git-apply).
4. Follow the instructions in [react-native-webrtc/Building WebRTC](https://github.com/react-native-webrtc/react-native-webrtc/blob/master/Documentation/BuildingWebRTC.md#building) to build the project.
5. Create a new release in this repo, attaching a zip of the `.xcframework`.

### Android

Tbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
From f7d3a4924a02bb7ea89c0a0ff9f41f9e36efb394 Mon Sep 17 00:00:00 2001
From: Antti Tapaninen <[email protected]>
Date: Thu, 26 Oct 2023 14:36:22 +0300
Subject: [PATCH] Don't ask camera permission if audio session mode is playback

Co-authored-by: mekya <[email protected]>
---
.../src/audio/voice_processing_audio_unit.mm | 108 +++++++++++-------
1 file changed, 66 insertions(+), 42 deletions(-)

diff --git a/sdk/objc/native/src/audio/voice_processing_audio_unit.mm b/sdk/objc/native/src/audio/voice_processing_audio_unit.mm
index 3905b6857a..5661ab455a 100644
--- a/sdk/objc/native/src/audio/voice_processing_audio_unit.mm
+++ b/sdk/objc/native/src/audio/voice_processing_audio_unit.mm
@@ -112,16 +112,23 @@ static OSStatus GetAGCState(AudioUnit audio_unit, UInt32* enabled) {
}

// Enable input on the input scope of the input element.
- UInt32 enable_input = 1;
- result = AudioUnitSetProperty(vpio_unit_, kAudioOutputUnitProperty_EnableIO,
- kAudioUnitScope_Input, kInputBus, &enable_input,
- sizeof(enable_input));
- if (result != noErr) {
- DisposeAudioUnit();
- RTCLogError(@"Failed to enable input on input scope of input element. "
- "Error=%ld.",
- (long)result);
- return false;
+ RTCAudioSessionConfiguration* webRTCConfiguration = [RTCAudioSessionConfiguration webRTCConfiguration];
+
+ if (webRTCConfiguration.mode != AVAudioSessionModeMoviePlayback) {
+ RTCLog(@"Enable input on the input scope of the input element.");
+ UInt32 enable_input = 1;
+ result = AudioUnitSetProperty(vpio_unit_, kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Input, kInputBus, &enable_input,
+ sizeof(enable_input));
+ if (result != noErr) {
+ DisposeAudioUnit();
+ RTCLogError(@"Failed to enable input on input scope of input element. "
+ "Error=%ld.",
+ (long)result);
+ return false;
+ }
+ } else {
+ RTCLog(@"Not Enable input on the input scope of the input element.");
}

// Enable output on the output scope of the output element.
@@ -155,34 +162,45 @@ static OSStatus GetAGCState(AudioUnit audio_unit, UInt32* enabled) {

// Disable AU buffer allocation for the recorder, we allocate our own.
// TODO(henrika): not sure that it actually saves resource to make this call.
- UInt32 flag = 0;
- result = AudioUnitSetProperty(
- vpio_unit_, kAudioUnitProperty_ShouldAllocateBuffer,
- kAudioUnitScope_Output, kInputBus, &flag, sizeof(flag));
- if (result != noErr) {
- DisposeAudioUnit();
- RTCLogError(@"Failed to disable buffer allocation on the input bus. "
- "Error=%ld.",
- (long)result);
- return false;
+ if (webRTCConfiguration.mode != AVAudioSessionModeMoviePlayback) {
+ RTCLog(@"Disable AU buffer allocation for the recorder, we allocate our own.");
+ UInt32 flag = 0;
+ result = AudioUnitSetProperty(
+ vpio_unit_, kAudioUnitProperty_ShouldAllocateBuffer,
+ kAudioUnitScope_Output, kInputBus, &flag, sizeof(flag));
+ if (result != noErr) {
+ DisposeAudioUnit();
+ RTCLogError(@"Failed to disable buffer allocation on the input bus. "
+ "Error=%ld.",
+ (long)result);
+ return false;
+ }
+ } else {
+ RTCLog(@"NOT Disable AU buffer allocation for the recorder, we allocate our own.");
}

// Specify the callback to be called by the I/O thread to us when input audio
// is available. The recorded samples can then be obtained by calling the
// AudioUnitRender() method.
- AURenderCallbackStruct input_callback;
- input_callback.inputProc = OnDeliverRecordedData;
- input_callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(vpio_unit_,
- kAudioOutputUnitProperty_SetInputCallback,
- kAudioUnitScope_Global, kInputBus,
- &input_callback, sizeof(input_callback));
- if (result != noErr) {
- DisposeAudioUnit();
- RTCLogError(@"Failed to specify the input callback on the input bus. "
- "Error=%ld.",
- (long)result);
- return false;
+ if (webRTCConfiguration.mode != AVAudioSessionModeMoviePlayback) {
+ RTCLog(@"Specify the callback to be called by the I/O thread to us when input audio");
+
+ AURenderCallbackStruct input_callback;
+ input_callback.inputProc = OnDeliverRecordedData;
+ input_callback.inputProcRefCon = this;
+ result = AudioUnitSetProperty(vpio_unit_,
+ kAudioOutputUnitProperty_SetInputCallback,
+ kAudioUnitScope_Global, kInputBus,
+ &input_callback, sizeof(input_callback));
+ if (result != noErr) {
+ DisposeAudioUnit();
+ RTCLogError(@"Failed to specify the input callback on the input bus. "
+ "Error=%ld.",
+ (long)result);
+ return false;
+ }
+ } else {
+ RTCLog(@"NOT Specify the callback to be called by the I/O thread to us when input audio");
}

state_ = kUninitialized;
@@ -204,15 +222,21 @@ static OSStatus GetAGCState(AudioUnit audio_unit, UInt32* enabled) {
LogStreamDescription(format);
#endif

- // Set the format on the output scope of the input element/bus.
- result =
- AudioUnitSetProperty(vpio_unit_, kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Output, kInputBus, &format, size);
- if (result != noErr) {
- RTCLogError(@"Failed to set format on output scope of input bus. "
- "Error=%ld.",
- (long)result);
- return false;
+ RTCAudioSessionConfiguration* webRTCConfiguration = [RTCAudioSessionConfiguration webRTCConfiguration];
+ if (webRTCConfiguration.mode != AVAudioSessionModeMoviePlayback) {
+ RTCLog(@"Setting the format on the output scope of the input element/bus because it's not movie mode");
+ // Set the format on the output scope of the input element/bus.
+ result =
+ AudioUnitSetProperty(vpio_unit_, kAudioUnitProperty_StreamFormat,
+ kAudioUnitScope_Output, kInputBus, &format, size);
+ if (result != noErr) {
+ RTCLogError(@"Failed to set format on output scope of input bus. "
+ "Error=%ld.",
+ (long)result);
+ return false;
+ }
+ } else {
+ RTCLog(@"NOT setting the format on the output sscope of the input element because it's movie mode");
}

// Set the format on the input scope of the output element/bus.
--
2.39.3 (Apple Git-145)

0 comments on commit a2eaa72

Please sign in to comment.