Callkit use bluetooth headset as audio output
Asked Answered
D

1

11

I'm working on VOIP with Callkit
It work fine, except audio output source
It always output audio by iPhone speaker

some of so answer said set AvAudioSession Option as AVAudioSessionCategoryOptionAllowBluetooth will work, but still failed
and I tried to set bluetooth headset as preferred, like this, failed

by the way, how to make ringtone broadcast by headset?
below is my code, follow the suggestion in this discussion, I configure AVAudioSession right after dialing and get coming call

- (void)getCall:(NSDictionary *)infoDic {

    CXCallUpdate *update = [[CXCallUpdate alloc]init];
    // config update

    NSUUID *uuid = [NSUUID UUID];
    [self.provider reportNewIncomingCallWithUUID:uuid update:update completion:^(NSError * _Nullable error) {
        if (error)
            NSLog(@"%@", error.localizedDescription);
    }];

    NSArray *video = @[@(ReceiveVideoReq), @(VideoCalling)];
    if ([video containsObject:@(self.client.callStage)])
        [ProviderManager configureAudio:true];
    else
        [ProviderManager configureAudio:false];
}

- (void)dialPhone:(BOOL)isVideo {

    CXHandle *handle = [[CXHandle alloc]initWithType:CXHandleTypePhoneNumber value:@"AAAA"];
    CXStartCallAction *start = [[CXStartCallAction alloc]initWithCallUUID:uuid handle:handle];
    start.video = isVideo;
    CXTransaction *trans = [[CXTransaction alloc]initWithAction:start];
    [self callControlReq:trans];

    [ProviderManager configureAudio:isVideo];
}

+ (void)configureAudio:(BOOL)isVideo {
    NSError *error=nil, *sessionError = nil;
    AVAudioSession *sess = [AVAudioSession sharedInstance];

    [sess setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionAllowBluetoothA2DP error:&sessionError];
    if (sessionError)
        NSLog(@"ERROR: setCategory %@", [sessionError localizedDescription]);

    if (isVideo)
        [sess setMode:@"AVAudioSessionModeVideoChat" error:&sessionError];
    else
        [sess setMode:@"AVAudioSessionModeVoiceChat" error:&sessionError];
    if (sessionError) {
        NSLog(@"ERROR: setCategory %@", [sessionError localizedDescription]);
    }

    [sess overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&sessionError];
    [[AVAudioSession sharedInstance] setActive:true withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

}
Director answered 7/7, 2017 at 9:41 Comment(2)
Hey @Director I know the question is a bit old but it looks like I'm hitting the same problem. Any news on this? Did you manage to fix it on your side?Stoddard
sorry, no luck. I give up bluetooth feature :(Director
P
1

After research, I found the root case of this issue. Open setting->Accessibility->Touch->Call Audio Routing, there are three option: Automatic, Bluetooth Headset, Speaker. Default is Automatic, that means if you answer a phone call(Include callkit), when you answer call by your bluetooth device, audio will route to bluetooth, if you answer the call in iPhone, it will route to receiver. So this actually not an issue, just system behavior.

And do not try to force switch to bluetooth by using [AVAudioSession setPreferredInput:], it will cause more serious issue. In my case: I call this force switch to bluetooth after audio connected, it worked, but when the bluetooth device disconnected, my audio completely not work and app not get any audio route change callback, even not work after connected bluetooth device again.

Pooka answered 11/5, 2020 at 9:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.