Skip to content

feat: hi-fi audio - #50

Merged
greenfrvr merged 13 commits into
masterfrom
hi-fi-audio
Aug 12, 2026
Merged

feat: hi-fi audio#50
greenfrvr merged 13 commits into
masterfrom
hi-fi-audio

Conversation

@greenfrvr

@greenfrvr greenfrvr commented Jun 25, 2026

Copy link
Copy Markdown

Summary by CodeRabbit

  • New Features
    • Added native camera previews for Android and iOS with camera selection, mirroring, sizing, and object-fit controls.
    • Camera previews can transfer directly into video calls without restarting capture.
    • Added a public CallFactory API for creating and disposing call resources.
  • Bug Fixes
    • Improved WebRTC factory, media-track, and audio resource lifecycle management.
    • Improved voice-processing and audio-device handling.
  • Documentation
    • Removed outdated Android audio-category setup instructions.

@greenfrvr greenfrvr self-assigned this Jun 25, 2026
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds per-call PeerConnectionFactory providers and registries on Android and iOS. It routes media resources through these providers. It adds native camera preview components with active-capture handoff to WebRTC tracks. JavaScript exports expose factory lifecycle and camera preview APIs.

Changes

Factory lifecycle, media routing, and camera preview

Layer / File(s) Summary
Android factory and media lifecycle
android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java, android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryRegistry.java, android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java, android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java, android/src/main/java/com/oney/WebRTCModule/WebRTCModuleOptions.java
Per-call factories own audio modules and media resources. Android module, peer connection, track, stream, screen-share, codec, and disposal paths use registry providers.
Android camera preview
android/src/main/java/com/oney/WebRTCModule/RTCCameraPreviewView.java, android/src/main/java/com/oney/WebRTCModule/FanoutCapturerObserver.java, android/src/main/java/com/oney/WebRTCModule/RTCCameraPreviewViewManager.java, android/src/main/java/com/oney/WebRTCModule/WebRTCModulePackage.java
Adds direct camera capture with prop reconciliation, renderer and downstream fan-out, handoff to video tracks, cleanup, and React Native registration.
iOS factory and module lifecycle
ios/RCTWebRTC/Utils/PeerConnectionFactory/*, ios/RCTWebRTC/WebRTCModule.h, ios/RCTWebRTC/WebRTCModule.m, ios/RCTWebRTC/WebRTCModule+RTCMediaStream.m, ios/RCTWebRTC/Utils/AudioDeviceModule/AudioDeviceModule.swift
Adds provider and registry lifecycle management, call-factory exports, current audio-device access, preview adoption, and ADM wrapper methods.
iOS camera preview
ios/RCTWebRTC/RTCCameraPreviewViewManager.h, ios/RCTWebRTC/RTCCameraPreviewViewManager.m
Adds a prop-driven camera preview view and manager with rendering, capture lifecycle, constraints, and capturer adoption.
JavaScript API surface
src/CallFactory.ts, src/RTCCameraPreviewView.ts, src/index.ts
Exports call-factory lifecycle methods, options, and the native camera preview component.
Android installation documentation
Documentation/AndroidInstallation.md
Removes the obsolete audio-category setup section.

Estimated code review effort: 4 (Complex) | ~75 minutes

Sequence Diagram(s)

sequenceDiagram
  participant App
  participant CallFactory
  participant WebRTCModule
  participant PeerConnectionFactoryRegistry
  App->>CallFactory: create(options)
  CallFactory->>WebRTCModule: createCallFactory(options)
  WebRTCModule->>PeerConnectionFactoryRegistry: create(bypassVoiceProcessing)
  PeerConnectionFactoryRegistry-->>WebRTCModule: provider
  App->>CallFactory: dispose()
  CallFactory->>WebRTCModule: disposeCallFactory()
  WebRTCModule->>PeerConnectionFactoryRegistry: disposeCurrent()
Loading
sequenceDiagram
  participant App
  participant CameraPreview
  participant WebRTCModule
  participant MediaTrackCreation
  App->>CameraPreview: activate with camera props
  CameraPreview->>WebRTCModule: register active preview
  MediaTrackCreation->>WebRTCModule: request preview adoption
  WebRTCModule->>CameraPreview: adopt or yield capture
  CameraPreview-->>MediaTrackCreation: capture handoff
  MediaTrackCreation->>MediaTrackCreation: attach capture to video track
Loading

Suggested reviewers: santhoshvai

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately identifies the substantial high-fidelity audio changes, although the pull request also includes camera preview and factory lifecycle changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hi-fi-audio

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greenfrvr
greenfrvr requested a review from santhoshvai July 17, 2026 13:05
@greenfrvr
greenfrvr marked this pull request as ready for review July 17, 2026 13:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java (1)

241-260: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate video prerequisites before creating the audio track.

For an audio-and-video request with no current Activity, the audio source and track are registered before this early return. Since no track ID reaches JavaScript, they remain leaked until factory or module teardown. Resolve the Activity first or dispose the partially created audio track before invoking the error callback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java` around
lines 241 - 260, Update getUserMedia around createAudioTrack and the
currentActivity null check so video prerequisites are validated before creating
and registering the audio track. Preserve the existing InvalidStateError
callback and return behavior, ensuring audio-only requests still create their
track normally.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@android/src/main/java/com/oney/WebRTCModule/FanoutCapturerObserver.java`:
- Around line 49-53: Update FanoutCapturerObserver.setDownstream and the
capturer lifecycle and frame-delivery methods to use one shared lock or
executor, serializing observer attachment with started-state callbacks and
downstream frame delivery. Ensure assignment and any onCapturerStarted
notification occur atomically with respect to concurrent start/stop operations,
preventing missed or incorrect lifecycle notifications.

In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java`:
- Around line 188-217: Update mixScreenAudioIntoBuffer so mixing is limited to
the writable microphone sample count, micSamples. Iterate only across
overlapping samples and remove the screen-only branch that writes beyond
micShorts’ range; preserve saturation for summed microphone and screen samples.
- Around line 87-89: Track whether the ADM in the factory was created by
buildAudioDeviceModule or supplied through options.injectedAudioDeviceModule,
and only release owned instances in dispose(); preserve shared injected
instances for reuse by later factories. In mixScreenAudioIntoBuffer(), clamp the
write loop to the mic buffer/sample count so screen audio cannot cause
micShorts.put to exceed its capacity.

In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryRegistry.java`:
- Around line 93-101: Update the replacement logic around currentFactory and
currentIsBareForkDefault to never dispose a live default factory directly.
Reject creation of the call factory while that default or its dependents remain
active, or route replacement through WebRTCModule’s ordered dependent cleanup
and disposeCallFactory before creating the new factory.
- Around line 102-105: Update the concurrent-factory branch in createCallFactory
to throw an appropriate exception instead of logging a warning and returning
existing. Ensure the native promise rejects and the second CallFactory cannot
proceed with ignored options or dispose the shared factory.

In `@android/src/main/java/com/oney/WebRTCModule/RTCCameraPreviewView.java`:
- Around line 115-125: Update commitProps and its running-configuration
comparison to snapshot captureWidth and captureHeight alongside facing and
device ID, then treat either dimension changing as configChanged so active
capture is restarted or reconfigured. Ensure the setters’ updated dimensions are
reflected in the committed configuration.
- Around line 241-261: Update yieldForAdoption() so handedOff and
clearActivePreview() are performed inside the captureExecutor task only after
confirming running, captureController, surfaceTextureHelper, and fanoutObserver
are all available. Do not mark the preview handed off or clear the active
preview before the prerequisite check succeeds, and preserve the existing
ownership transfer and null return behavior.
- Around line 268-280: Move the `fanoutObserver` snapshot and related
renderer-detachment decision into the `captureExecutor` task, so
`fanoutObserver` is read on its owning executor before calling
`fanout.setRenderer(null)`. Preserve the existing `releaseRenderer` behavior and
ensure detachment occurs for adopted captures before
`surfaceViewRenderer.release()`.

In `@android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java`:
- Around line 64-65: Make activeCameraPreview thread-safe across React lifecycle
callbacks and WebRTC executor access: synchronize or otherwise safely publish
writes and reads, including the getUserMedia path and the callbacks around lines
275-287. Ensure getUserMedia observes the currently active preview before
attempting to open another camera.
- Around line 153-185: Update disposeCallFactory() to abort factory disposal
when any owned PeerConnection or track fails to dispose, rather than continuing
to factoryRegistry.disposeCurrent(). Track failures, PeerConnection failures,
and any remaining local streams must cause the promise to reject while leaving
the factory and ADM undisposed; only resolve after all dependents are
successfully removed and the ordering invariant is satisfied.

In `@ios/RCTWebRTC/RTCCameraPreviewViewManager.m`:
- Around line 195-228: Serialize all `_captureController` access in the capture
queue: update the start, stop, and constraint-update branches in
`RTCameraPreviewViewManager` to resolve the controller inside `_captureQueue`
rather than snapshotting it beforehand. Before creating or starting capture,
re-check the latest `isActive`/`_capturing` state and abort or stop when
inactive, while preserving queued stop and constraint updates.
- Around line 204-207: Update the fresh preview-controller initialization in the
capture setup around _captureController and VideoCaptureController so the
existing enableMultitaskingCameraAccess setting is also passed to an adopted
preview controller. Preserve the current capturer and constraints initialization
while ensuring both fresh-track and handoff paths use the same multitasking
camera access option.

In `@ios/RCTWebRTC/WebRTCModule.m`:
- Around line 215-219: Update disposeCallFactory to dispose all factory-owned
peer connections and media tracks before invoking self.factoryRegistry
disposeCurrent. Preserve the existing promise resolution, and ensure factory
teardown occurs only after those dependent WebRTC objects have been released.

In `@src/CallFactory.ts`:
- Around line 25-38: Scope each CallFactory handle to its native factory ID: in
src/CallFactory.ts lines 25-38, store the ID returned by createCallFactory and
pass that ID from dispose; in ios/RCTWebRTC/WebRTCModule.m lines 202-219,
resolve creation with the provider ID and require it when disposing; in
ios/RCTWebRTC/Utils/PeerConnectionFactory/PeerConnectionFactoryRegistry.swift
lines 66-86, reject a second live factory instead of reusing the existing
provider and only dispose when the requested ID matches.

---

Outside diff comments:
In `@android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java`:
- Around line 241-260: Update getUserMedia around createAudioTrack and the
currentActivity null check so video prerequisites are validated before creating
and registering the audio track. Preserve the existing InvalidStateError
callback and return behavior, ensuring audio-only requests still create their
track normally.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e0f04110-1d20-4236-b823-20142a7d54de

📥 Commits

Reviewing files that changed from the base of the PR and between 8972b28 and 30614ca.

📒 Files selected for processing (19)
  • android/src/main/java/com/oney/WebRTCModule/FanoutCapturerObserver.java
  • android/src/main/java/com/oney/WebRTCModule/GetUserMediaImpl.java
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryRegistry.java
  • android/src/main/java/com/oney/WebRTCModule/RTCCameraPreviewView.java
  • android/src/main/java/com/oney/WebRTCModule/RTCCameraPreviewViewManager.java
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModulePackage.java
  • ios/RCTWebRTC/RTCCameraPreviewViewManager.h
  • ios/RCTWebRTC/RTCCameraPreviewViewManager.m
  • ios/RCTWebRTC/Utils/AudioDeviceModule/AudioDeviceModule.swift
  • ios/RCTWebRTC/Utils/PeerConnectionFactory/PeerConnectionFactoryProvider.swift
  • ios/RCTWebRTC/Utils/PeerConnectionFactory/PeerConnectionFactoryRegistry.swift
  • ios/RCTWebRTC/WebRTCModule+RTCMediaStream.m
  • ios/RCTWebRTC/WebRTCModule.h
  • ios/RCTWebRTC/WebRTCModule.m
  • src/CallFactory.ts
  • src/RTCCameraPreviewView.ts
  • src/index.ts

Comment thread android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java Outdated
Comment thread android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java Outdated
Comment thread ios/RCTWebRTC/RTCCameraPreviewViewManager.m
Comment thread ios/RCTWebRTC/RTCCameraPreviewViewManager.m
Comment thread ios/RCTWebRTC/WebRTCModule.m
Comment thread src/CallFactory.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java (1)

84-96: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Release adm if factory construction fails.
dispose() cleans up the module on the normal path, but if createPeerConnectionFactory() throws, this native resource is left allocated. Wrap factory construction and release adm on the failure path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java`
around lines 84 - 96, Update the factory construction flow around
PeerConnectionFactory.Builder.createPeerConnectionFactory() to release the
AudioDeviceModule via adm.release() if construction throws, then rethrow the
original failure. Preserve the existing successful return path and normal
dispose() ownership behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java`:
- Around line 84-96: Update the factory construction flow around
PeerConnectionFactory.Builder.createPeerConnectionFactory() to release the
AudioDeviceModule via adm.release() if construction throws, then rethrow the
original failure. Preserve the existing successful return path and normal
dispose() ownership behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1255f264-1c0e-4f71-8f78-3c91e8a18a5b

📥 Commits

Reviewing files that changed from the base of the PR and between 30614ca and 4214690.

📒 Files selected for processing (7)
  • Documentation/AndroidInstallation.md
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryRegistry.java
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModuleOptions.java
  • ios/RCTWebRTC/RTCCameraPreviewViewManager.m
  • ios/RCTWebRTC/WebRTCModule.m
💤 Files with no reviewable changes (2)
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModuleOptions.java
  • Documentation/AndroidInstallation.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryRegistry.java
  • ios/RCTWebRTC/WebRTCModule.m
  • ios/RCTWebRTC/RTCCameraPreviewViewManager.m
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java (2)

103-112: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Apply the bypass voice-profile capture settings.

When bypassVoiceProcessing is true, stereoInputEnabled currently has no effect and the audio source remains the default voice-communication path instead of raw MediaRecorder.AudioSource.MIC. Enable both builders matching the documented profile, or remove the options and update callers.

Proposed fix
             builder.setUseHardwareAcousticEchoCanceler(false)
                     .setUseHardwareNoiseSuppressor(false)
                     .setUseStereoOutput(true)
-                    // .setUseStereoInput(options.stereoInputEnabled)
-                    // .setAudioSource(MediaRecorder.AudioSource.MIC)
+                    .setUseStereoInput(options.stereoInputEnabled)
+                    .setAudioSource(MediaRecorder.AudioSource.MIC)
                     .setOutputSampleRate(nativeOutputSampleRate(options.context));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java`
around lines 103 - 112, Update the bypassVoiceProcessing branch in
PeerConnectionFactoryProvider so it applies options.stereoInputEnabled through
setUseStereoInput and selects MediaRecorder.AudioSource.MIC via setAudioSource,
while preserving the existing hardware-processing, stereo-output, and native
sample-rate settings.

84-96: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Release adm when build() fails.

createAudioDeviceModule() hands callers ownership of native audio resources. If the PeerConnectionFactory builder setup or createPeerConnectionFactory() throws, PeerConnectionFactoryProvider.build() returns without owning the AudioDeviceModule, so adm.release() is never called. Catch and wrap the failure path to release adm, then rethrow the original exception.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java`
around lines 84 - 96, Update PeerConnectionFactoryProvider.build() to guard the
PeerConnectionFactory builder setup and createPeerConnectionFactory() call with
failure handling that invokes adm.release() when any step throws, then rethrows
the original exception without altering successful creation behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java`:
- Around line 103-112: Update the bypassVoiceProcessing branch in
PeerConnectionFactoryProvider so it applies options.stereoInputEnabled through
setUseStereoInput and selects MediaRecorder.AudioSource.MIC via setAudioSource,
while preserving the existing hardware-processing, stereo-output, and native
sample-rate settings.
- Around line 84-96: Update PeerConnectionFactoryProvider.build() to guard the
PeerConnectionFactory builder setup and createPeerConnectionFactory() call with
failure handling that invokes adm.release() when any step throws, then rethrows
the original exception without altering successful creation behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 696ae0ab-38b6-4699-9bd2-bff0f9a84e58

📥 Commits

Reviewing files that changed from the base of the PR and between f6dcf78 and a6f6100.

📒 Files selected for processing (1)
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryProvider.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java (1)

154-155: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Reject factory-disposal errors.

If disposeCurrentFactoryOrdered() throws, this executor task exits without resolving or rejecting promise. Catch the exception and call promise.reject("E_FACTORY_DISPOSE", e).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java` around lines
154 - 155, Update disposeCallFactory to catch exceptions thrown by
disposeCurrentFactoryOrdered() within the executor task and reject the promise
with code "E_FACTORY_DISPOSE" and the caught exception; continue resolving the
promise with the disposal result when no exception occurs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@ios/RCTWebRTC/Utils/PeerConnectionFactory/PeerConnectionFactoryRegistry.swift`:
- Around line 111-134: Separate final reference release from factory disposal in
PeerConnectionFactoryRegistry.disposeCurrent(): decrement or clear the registry
reference and return whether it was the final release without calling
factory.dispose(). Add a dedicated final factory-disposal API or caller wrapper
that performs cleanup in Android order—release reference, dispose peer
connections, dispose tracks, then dispose the factory—and update callers
accordingly. Verify the iOS example project builds successfully.

---

Outside diff comments:
In `@android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java`:
- Around line 154-155: Update disposeCallFactory to catch exceptions thrown by
disposeCurrentFactoryOrdered() within the executor task and reject the promise
with code "E_FACTORY_DISPOSE" and the caught exception; continue resolving the
promise with the disposal result when no exception occurs.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 398f1ec4-eee7-45f3-ad6e-51bbca81826f

📥 Commits

Reviewing files that changed from the base of the PR and between a6f6100 and c253112.

📒 Files selected for processing (3)
  • android/src/main/java/com/oney/WebRTCModule/PeerConnectionFactoryRegistry.java
  • android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java
  • ios/RCTWebRTC/Utils/PeerConnectionFactory/PeerConnectionFactoryRegistry.swift

@greenfrvr
greenfrvr merged commit 1be1f5b into master Aug 12, 2026
5 of 6 checks passed
@greenfrvr
greenfrvr deleted the hi-fi-audio branch August 12, 2026 08:40
github-actions Bot pushed a commit that referenced this pull request Aug 12, 2026
## [145.3.0](v145.2.0...v145.3.0) (2026-08-12)

### Features

* hi-fi audio ([#50](#50)) ([1be1f5b](1be1f5b))

### Bug Fixes

* iOS boolean conversion never parsed false ([#59](#59)) ([a0dac58](a0dac58))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 145.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

greenfrvr added a commit to GetStream/stream-video-js that referenced this pull request Aug 12, 2026
### 💡 Overview

**Hi-fi audio**
* Public api for stereo output enabling is simplified.
`callManager.start({ audioRole: 'listener' })` enables stereo output for
both platforms. Should be invoked on pre-join stage.
* Wired stereo input enable/disable flag for Android. For now it is
omitted.

**Presented media engine**
* Media engine is a layer responsible for creating/disposing WebRTC peer
connection factory in runtime during call join/leave stages. Peer
connection factory and audio device module instances are defined on
per-call basis. Only one factory instance can be created at a time. Web
resolves to a no-op engine.
* Guarded join/leave race. There are several implicit factory creators
during join flow: `getGenericSdp` and `initPublisherAndSubscriber`
(RTCPeerConnection constructor). The guard prevents creating new
instance if the join flow was interrupted by leave invocation.

**Made RN lobby independent from webrtc**
* Presented new video preview component, which uses video capturer
directly without creating local tracks. That video capturer instance is
passed later to a local track as a source of media
* Made device managers mute/unmute on pre-join stage update
corresponding state in an optimistic manner. That state is applied
during tracks publishing.

**Hardened call manager and audio wiring pipeline**
* Public call manager now won't invoke audio session configuration
explicitly. Instead it stores configuration params, which are applied
during join flow. Those params may override default call settings (e.g.
deviceEndpointType). Params are disposed during leave stage.
* Audio engine interruptions subscription for callingx is now managed
during join/leave, instead of single global subscription.

🎫 Ticket: https://linear.app/stream/issue/RN-402/hi-fi-audio

📑 Docs: GetStream/docs-content#1444

Corresponding WebRTC PR:
GetStream/react-native-webrtc#50


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added per-call WebRTC media engine support with configurable
providers.
* Added React Native lobby camera previews with on-demand permissions
and optimistic camera state.
* Added iOS controls for microphone mute mode and recording preparation.
* Added audio-engine subscription management for CallingX and in-call
behavior.

* **Bug Fixes**
* Prevented join/leave race conditions from continuing setup after
leaving.
* Improved React Native media capture, camera controls, and device-state
handling.
* Improved iOS audio stability when no active audio device is available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
gabrieldonadel pushed a commit to gabrieldonadel/GetStream-react-native-webrtc that referenced this pull request Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants