扬声器发出CallKit问题,接到来电后自动开启

时间:2018-05-02 10:27:52

标签: ios swift avaudiosession tokbox callkit

我正在使用CallKitTokBox以及它如何处理一个错误,即在收到呼叫后,扬声器变为活动状态,无法通过点击它来禁用。电话是从主动扬声器开始的,我认为这是一个错误,但WhatsApp和FBMassenger使用了相同的自定义呼叫屏幕视图,但是他们的扬声器在接到电话后变为非活动状态,我搜索过,没有相关的答案我被发现所以远。

TokBox中,他们提供了OTDefaultAudioDevice.hOTDefaultAudioDevice.m文件,他们用CallKitSpeakerBox配置了所有关于音频的文件。我在哪里找到了以下配置:

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

已按以下方式使用:

- (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;
}

AVAudioSessionPortOverrideSpeaker用于所有设备,我认为这是启用扬声器的主要原因,但我不确切知道。即

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

到目前为止,是否有人有任何建议或在此纠正过该州的任何人?

我也相信像我这样的很多人都会遇到这个问题。

任何帮助都会很明显。

由于

2 个答案:

答案 0 :(得分:1)

我已经完成了opentok支持,他们认真对待这个问题,并且由于服务仅用于视频聊天,因此他们在CallKit UI中启用了扬声器启用。要通过使用他们的Objective C类(OTDefaultAudioDevice.hOTDefaultAudioDevice.m来禁用或仅用于音频调用,那么我们必须在.m文件中注释以下行。

audioOptions |= AVAudioSessionCategoryOptionDefaultToSpeaker;

希望它能挽救很多日子。

感谢。

答案 1 :(得分:1)

最后,我设法解决了这个问题。解决方案是@AbhishekMitra和我发现自己的混合物

首先,我使用DefaultAudioDevice.swift替换Objective C类OTDefaultAudioDevice: https://github.com/opentok/opentok-ios-sdk-samples-swift/blob/master/Custom-Audio-Driver/Custom-Audio-Driver/DefaultAudioDevice.swift

相当于objc,注释出Abhishek建议的行,并在同一函数中添加了另一行,即:

configureAudioSessionWithDesiredAudioRoute(desiredAudioRoute: DefaultAudioDevice.kAudioDeviceHeadset)

这是整个功能

fileprivate func setupAudioSession() {
        let session = AVAudioSession.sharedInstance()
        
        previousAVAudioSessionCategory = session.category
        avAudioSessionMode = session.mode
        avAudioSessionPreffSampleRate = session.preferredSampleRate
        avAudioSessionChannels = session.inputNumberOfChannels
        do {
            try session.setPreferredSampleRate(Double(DefaultAudioDevice.kSampleRate))
            try session.setPreferredIOBufferDuration(0.01)
            let audioOptions = AVAudioSessionCategoryOptions.mixWithOthers.rawValue |
                AVAudioSessionCategoryOptions.allowBluetooth.rawValue
                //|
                //AVAudioSessionCategoryOptions.defaultToSpeaker.rawValue
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord, mode: AVAudioSessionModeVideoChat, options: AVAudioSessionCategoryOptions(rawValue: audioOptions))
            setupListenerBlocks()
            //set the audio to headset
            configureAudioSessionWithDesiredAudioRoute(desiredAudioRoute: DefaultAudioDevice.kAudioDeviceHeadset)
            
            try session.setActive(true)
        } catch let err as NSError {
            print("Error setting up audio session \(err)")
        } catch {
            print("Error setting up audio session")
        }
    }

这最终解决了我的问题,当通话激活时,设备不在扬声器上。如果您有任何问题,请告诉我。

这一行的objc版本是:

[self configureAudioSessionWithDesiredAudioRoute:
                 AUDIO_DEVICE_HEADSET];