Search code examples
iosswiftavaudiosessiontokboxcallkit

CallKit issue with Speaker, Automatically turned On after receiving the call


I'm using CallKit with TokBox and some how it is working with one bug, i.e after receiving the call, the speaker becomes active and can not be disabled by tapping on it. Call is starting with active speaker which I think is a bug, but WhatsApp and FBMassenger have used the same with their custom calling screen View, but their speaker become inactive after receiving the call, which I searched and no relevant answer I have been found so far.

In TokBox they provided OTDefaultAudioDevice.h and OTDefaultAudioDevice.m file from where they configured all about audio with CallKitSpeakerBox. Where I found following configuration:

#define AUDIO_DEVICE_HEADSET     @"AudioSessionManagerDevice_Headset"
#define AUDIO_DEVICE_BLUETOOTH   @"AudioSessionManagerDevice_Bluetooth"
#define AUDIO_DEVICE_SPEAKER     @"AudioSessionManagerDevice_Speaker"

Which has been used as following way:

- (BOOL)configureAudioSessionWithDesiredAudioRoute:(NSString*)desiredAudioRoute
{
    OT_AUDIO_DEBUG(@"configureAudioSessionWithDesiredAudioRoute %@",desiredAudioRoute);

    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *err;

    //ios 8.0 complains about Deactivating an audio session that has running
    // I/O. All I/O should be stopped or paused prior to deactivating the audio
    // session. Looks like we can get away by not using the setActive call
    if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"7.0")) {
        // close down our current session...
        [audioSession setActive:NO error:nil];
    }

    if ([AUDIO_DEVICE_BLUETOOTH isEqualToString:desiredAudioRoute]) {
        [self setBluetoothAsPrefferedInputDevice];
    }

    if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"7.0")) {
        // Set our session to active...
        if (![audioSession setActive:YES error:&err]) {
            NSLog(@"unable to set audio session active: %@", err);
            return NO;
        }
    }

    if ([AUDIO_DEVICE_SPEAKER isEqualToString:desiredAudioRoute]) {
        // replace AudiosessionSetProperty (deprecated from iOS7) with
        // AVAudioSession overrideOutputAudioPort
#if !(TARGET_OS_TV)
        [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                        error:&err];
#endif
    } else
    {
        [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone
                                        error:&err];
    }

    return YES;
}

Where AVAudioSessionPortOverrideSpeaker used for all devices, which I believe is the main reason for becoming enabled speaker, though I don't know exactly. i.e

if ([AUDIO_DEVICE_SPEAKER isEqualToString:desiredAudioRoute]) {
            // replace AudiosessionSetProperty (deprecated from iOS7) with
            // AVAudioSession overrideOutputAudioPort
    #if !(TARGET_OS_TV)
            [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                            error:&err];
    #endif
        } else
        {
            [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideNone
                                            error:&err];
        }
}

Does any one have any suggestion or does any one here who have corrected that state so far?

I also believe that many like me is going through this issue.

Any help will be appreciable.

Thanks


Solution

  • I have gone through the opentok support and they took this issue seriously and due to the service was made only for video chat, they made that speaker enable in the CallKit UI for that reason. To make it disable or to use only for audio call by using their Objective C class which is namely OTDefaultAudioDevice.h and OTDefaultAudioDevice.m, then we have to comment following line in .m file.

    audioOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;

    Hope it will save many's day.

    Thanks.