react-native-incall-manager coop
Bug report
-
[x] I've checked the example to reproduce the issue.
-
Reproduced on:
-
[x] Android
-
[ ] iOS
Description
I'm using https://github.com/react-native-webrtc/react-native-incall-manager to manage audio during call ... Works fine, also with BT device. However, as soon as I also use https://github.com/react-native-webrtc/react-native-callkeep , things start going south ...
Problem 1: the motivation to use RNCallKeep is ONLY to keep the call alive, on Android, when phone is put to sleep. I'm using websockets for some realtime communication, registered and handled in js, however they get killed by OS if I dont use callkeep ... Which part of callkeep is responsible for OS preventing from killing app/connections/js thread, is it the telecomManager.placeCall (internal API)? Dont see anything else potentially capable of that ...
Problem 2: Given the above, i have to use callkeep for calls in background. But it doesnt play nicely with incallmanager
- callkeep grabs audio context internally, if this happens AFTER incallmanager obtains it, incallmanager is no longer usable (nor can it "steal the audio context from callkeep)
- have to use
didActivateAudioSessionevent with some timeout for detecting when is it safe to initialize incallmanager (it still works even with audio context already owned by callkeep) - even when I do the above, with BT device it seems TelecomManager? is messing with it quite a lot, sometimes it disconnects randomly, etc ... Without callkeep incallmanager works fine even with BT ...
I'm using callkeep in self-managed mode, manage permissions independently, so really the only value (crucial though) it provides for my use-case is that "magic" that prevents the app from getting websockets in js disconnected ...
Steps to Reproduce
Versions
- Callkeep: 4.2.0
- React Native: 0.64.1
- iOS: N/A
- Android: 11
- Phone model: Pixel 4XL
Logs
N/A
Paste here
N/A
@Kelt did you find any solution
@MusabBasheer not yet unfortunately
I got some issues with IncallManager as well, more detail: turn loud speaker on/off
Turn out I didnt call IncallManager.setup(). I put a call before any callkeep call then it works
Not sure which functionalities you need from IncallManager?
As far as I remember we had permission issue. So calling setup function after audio permissions granted, allow you to correctly turn on/off loud speaker.
hi @namnm , can u provide more code, where u put inCallManager.setup()?, i tried to call it's when other uther joined call + call setSpeaker... , but not working
hey @fukemy did you manage to turn the speaker on on incoming call? i am struggling to make incallmanager work with callkeep, on outgoing call after the call was connected the audio is routed correctly to the speakers, but on incoming call it goes to earpiece. sometimes when the app is freshly started the audio will go through the speakers even on incoming calls, but after that it will go back on playing through the earpiece
@Romick2005 did you also use incallmanager with callkeep?
@Romick2005 did you also use incallmanager with callkeep?
Yes. If you call InCallManager.start({media: "video"}) it will call InCallManager.setKeepScreenOn(true) and InCallManager.setForceSpeakerphoneOn(true) functions for you.
@Romick2005
Yes. If you call InCallManager.start({media: "video"}) it will call InCallManager.setKeepScreenOn(true) and InCallManager.setForceSpeakerphoneOn(true) functions for you.
yeah i know that, it handles everything automatically for you, on outgoing call it works great, but on incoming call it goes to the earpiece for my android device. in logcat it says that the speaker was set, but in reality it doesn't go there for some reason. do you remember if it worked for you in incoming calls too?
It is still working fine for me. I guess you need to have proper timing to call start function. Can you please try to call it with some timeout just to check my theory? You should call start after the call connection is established, not before as webrtc can override it
yes of course. where do you think would be the perfect place to call it? currently i am calling it at the answerCall event, previously i tried it at incomingCall event. maybe i need it to call at callConnected? after a small delay?
hey man, i can't express how much i appreciate you rn hahaa, i struggled to make this work for a long time. your theory was right, i wired the start function to a button press while on the video call screen and the audio was routed to the speakers. such a simple solution (now i will experiment to fire the function automatically at the right moment), thank you!
We use callkeep to handle loud speaker, just has been supported recently by the callkeep package
It is still working fine for me. I guess you need to have proper timing to call start function. Can you please try to call it with some timeout just to check my theory? You should call start after the call connection is established, not before as webrtc can override it
Hi @Romick2005 , I called this method InCallManager.start({media: "video"}) like this:
useEffect(() => {
InCallManager.start({media: "video"})
, [])
Does this the best place to call? Sometimes I got no audio with IOS incoming call, I still do not solved this
The best place is when you have setup peer to peer connection and then adjust audio session with InCallManager.start().
setup peer to peer connection
Did you mean the 'event' onTrack of peerconnection like this:
this.pc.addEventListener('track', event => {
if (event && event.streams.length > 0) {
if (this.onStreamListener && typeof this.onStreamListener === 'function') {
this.onStreamListener(event.streams[0])
}
}
})
We use callkeep to handle loud speaker, just has been supported recently by the callkeep package
yeah, but does it work with external devices like bluetooth headphones or wired earphones?
setup peer to peer connection
Did you mean the 'event' onTrack of peerconnection like this:
this.pc.addEventListener('track', event => { if (event && event.streams.length > 0) { if (this.onStreamListener && typeof this.onStreamListener === 'function') { this.onStreamListener(event.streams[0]) } } })
Actually after checking microphone and camera permissions -> then mediaDevices.getUserMedia and new RTCPeerConnection -> then you can call InCallManager.start
thanks, I will check
We use callkeep to handle loud speaker, just has been supported recently by the callkeep package
yeah, but does it work with external devices like bluetooth headphones or wired earphones?
Yes, this incall manager has issue with those device, that is why we switched to use callkeep api. The api need uuid of the call to change audio route, we support multiple calls at the same time with hold feature so it makes sense.
Yes, this incall manager has issue with those device, that is why we switched to use callkeep api. The api need uuid of the call to change audio route, we support multiple calls at the same time with hold feature so it makes sense.
does it handle it automatically or do you code it programatically when let's say a bluetooth device was connected?
does it handle it automatically or do you code it programatically when let's say a bluetooth device was connected?
It does, that is the whole point of using callkeep, it has CallKit/ConnectionService native below which handle those automatically.