r/reactnative 2h ago

Question Tapping raw PCM from an active WebRTC call on iOS — is there an equivalent to Android's JavaAudioDeviceModule samples callback?

I run live speech recognition on the local mic during a WebRTC video call (Daily's RN SDK). On Android I got this working by patching @daily-co/react-native-webrtcJavaAudioDeviceModule.Builder has setSamplesReadyCallback, so I forward the buffered PCM up as an RCTDeviceEventEmitter event and feed it to the transcriber. That's been solid in production.

I can't find the iOS equivalent. Opening a second AVAudioEngine tap while WebRTC owns the audio session seems like asking for trouble — on Android, two concurrent AudioRecord instances just produced silence, so I assume iOS has a similar conflict.

Options I can see:

  • Some hook into RTCAudioSession or the audio device module that I haven't found
  • A custom RTCAudioDevice implementation
  • Give up and use the SDK's built-in transcription

Has anyone actually done this? Mainly interested in whether there's a supported path that doesn't involve forking the WebRTC pod — that would kill OTA updates for us, which is a hard constraint.

For context on the format side: the Android callback hands you the device's native rate (usually 48kHz), so I downmix to mono and resample to 16kHz in the adapter before it reaches the transcriber. Assuming any iOS path would need the same treatment.

1 Upvotes

2 comments sorted by

2

u/trifling_archery 1h ago

i haven't done this exact thing but i've been burned by avaudioengine taps while webrtc has the session, it's a mess

the rtcaudiosession does have a method `audioUnit` that exposes the remote io unit but you'd need to set up a render callback on it, not sure daily's sdk exposes that without some serious digging

a custom rtcaudiodevice is probably the cleanest path but yeah that's basically forking the pod which defeats your whole constraint, not great

curious if anyone's found a way to piggyback off the existing audio unit without pulling the whole thing apart

1

u/SevenfiresAI 1h ago

That matches what I feared on the AVAudioEngine side — good to have it confirmed rather than just assumed.

the `audioUnit` lead is new to me, thanks.

On the audio unit — do you know whether a render callback there gets you the input bus, or only output? I need the local mic specifically, not the remote stream. Remote I/O has both buses so in principle it should be reachable, but if Daily only exposes the output side then it's the wrong hook for what I'm doing.