react-native-callkeep icon indicating copy to clipboard operation
react-native-callkeep copied to clipboard

react-native-incall-manager coop

Open Kelt opened this issue 4 years ago • 23 comments

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 didActivateAudioSession event 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 avatar Jun 15 '21 13:06 Kelt

@Kelt did you find any solution

MusabBasheer avatar Jun 21 '21 21:06 MusabBasheer

@MusabBasheer not yet unfortunately

Kelt avatar Jun 22 '21 06:06 Kelt

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?

namnm avatar Jun 24 '21 09:06 namnm

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.

Romick2005 avatar Jun 24 '21 11:06 Romick2005

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

fukemy avatar Oct 21 '22 03:10 fukemy

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

wilmxre avatar Nov 01 '23 15:11 wilmxre

@Romick2005 did you also use incallmanager with callkeep?

wilmxre avatar Nov 01 '23 15:11 wilmxre

@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 avatar Nov 01 '23 15:11 Romick2005

@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?

wilmxre avatar Nov 01 '23 15:11 wilmxre

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

Romick2005 avatar Nov 01 '23 16:11 Romick2005

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?

wilmxre avatar Nov 01 '23 16:11 wilmxre

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!

wilmxre avatar Nov 01 '23 16:11 wilmxre

We use callkeep to handle loud speaker, just has been supported recently by the callkeep package

namnm avatar Nov 02 '23 01:11 namnm

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

fukemy avatar Nov 02 '23 02:11 fukemy

The best place is when you have setup peer to peer connection and then adjust audio session with InCallManager.start().

Romick2005 avatar Nov 02 '23 06:11 Romick2005

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])
                }            
            }
        })

fukemy avatar Nov 02 '23 06:11 fukemy

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?

wilmxre avatar Nov 02 '23 06:11 wilmxre

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

Romick2005 avatar Nov 02 '23 07:11 Romick2005

thanks, I will check

fukemy avatar Nov 02 '23 07:11 fukemy

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.

namnm avatar Nov 02 '23 14:11 namnm

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?

wilmxre avatar Nov 02 '23 14:11 wilmxre

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.

namnm avatar Nov 02 '23 23:11 namnm